merge with master

This commit is contained in:
lukashov
2015-11-23 17:48:59 +01:00
5371 changed files with 1239495 additions and 2138470 deletions
+156 -155
View File
@@ -1,31 +1,32 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT OWNER 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.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*****************************************************************************
@@ -135,15 +136,15 @@ Description Defines the messages supported by the Access Stratum sublayer
#define ESM_FAILURE (19)
typedef enum nas_cause_s {
NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_NOT_ALLOWED,
NAS_CAUSE_PLMN_NOT_ALLOWED = PLMN_NOT_ALLOWED,
NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED = TRACKING_AREA_NOT_ALLOWED,
NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA = NO_SUITABLE_CELLS_IN_TRACKING_AREA,
NAS_CAUSE_NETWORK_FAILURE = NETWORK_FAILURE,
NAS_CAUSE_ESM_FAILURE = ESM_FAILURE
NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_NOT_ALLOWED,
NAS_CAUSE_PLMN_NOT_ALLOWED = PLMN_NOT_ALLOWED,
NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED = TRACKING_AREA_NOT_ALLOWED,
NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA = NO_SUITABLE_CELLS_IN_TRACKING_AREA,
NAS_CAUSE_NETWORK_FAILURE = NETWORK_FAILURE,
NAS_CAUSE_ESM_FAILURE = ESM_FAILURE
} nas_cause_t;
/*
@@ -154,32 +155,32 @@ typedef enum nas_cause_s {
/* Error code */
typedef enum nas_error_code_s {
AS_SUCCESS = 1, /* Success code, transaction is going on */
AS_TERMINATED_NAS, /* Transaction terminated by NAS */
AS_TERMINATED_AS, /* Transaction terminated by AS */
AS_FAILURE /* Failure code */
AS_SUCCESS = 1, /* Success code, transaction is going on */
AS_TERMINATED_NAS, /* Transaction terminated by NAS */
AS_TERMINATED_AS, /* Transaction terminated by AS */
AS_FAILURE /* Failure code */
} nas_error_code_t;
/* Core network domain */
typedef enum core_network_s {
AS_PS = 1, /* Packet-Switched */
AS_CS /* Circuit-Switched */
AS_PS = 1, /* Packet-Switched */
AS_CS /* Circuit-Switched */
} core_network_t;
/* SAE Temporary Mobile Subscriber Identity */
typedef struct as_stmsi_s {
UInt8_t MMEcode; /* MME code that allocated the GUTI */
UInt32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */
uint8_t MMEcode; /* MME code that allocated the GUTI */
uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */
} as_stmsi_t;
/* Dedicated NAS information */
typedef struct as_nas_info_s {
UInt32_t length; /* Length of the NAS information data */
Byte_t *data; /* Dedicated NAS information data container */
uint32_t length; /* Length of the NAS information data */
Byte_t* data; /* Dedicated NAS information data container */
} as_nas_info_t;
/* Radio Access Bearer identity */
typedef UInt8_t as_rab_id_t;
typedef uint8_t as_rab_id_t;
/****************************************************************************/
/************************ G L O B A L T Y P E S ************************/
@@ -198,9 +199,9 @@ typedef UInt8_t as_rab_id_t;
*/
typedef struct broadcast_info_ind_s {
#define PLMN_LIST_MAX_SIZE 6
PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */
ci_t cellID; /* Identity of the cell serving the listed PLMNs */
tac_t tac; /* Code of the tracking area the cell belongs to */
PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */
ci_t cellID; /* Identity of the cell serving the listed PLMNs */
tac_t tac; /* Code of the tracking area the cell belongs to */
} broadcast_info_ind_t;
/*
@@ -225,8 +226,8 @@ typedef struct broadcast_info_ind_s {
* PLMN to camp on.
*/
typedef struct cell_info_req_s {
plmn_t plmnID; /* Selected PLMN identity */
Byte_t rat; /* Bitmap - set of radio access technologies */
plmn_t plmnID; /* Selected PLMN identity */
Byte_t rat; /* Bitmap - set of radio access technologies */
} cell_info_req_t;
/*
@@ -235,12 +236,12 @@ typedef struct cell_info_req_s {
* is selected to camp on.
*/
typedef struct cell_info_cnf_s {
UInt8_t errCode; /* Error code */
ci_t cellID; /* Identity of the cell serving the selected PLMN */
tac_t tac; /* Code of the tracking area the cell belongs to */
AcT_t rat; /* Radio access technology supported by the cell */
UInt8_t rsrq; /* Reference signal received quality */
UInt8_t rsrp; /* Reference signal received power */
uint8_t errCode; /* Error code */
ci_t cellID; /* Identity of the cell serving the selected PLMN */
tac_t tac; /* Code of the tracking area the cell belongs to */
AcT_t rat; /* Radio access technology supported by the cell */
uint8_t rsrq; /* Reference signal received quality */
uint8_t rsrp; /* Reference signal received power */
} cell_info_cnf_t;
/*
@@ -248,8 +249,8 @@ typedef struct cell_info_cnf_s {
* AS may change cell selection if a more suitable cell is found.
*/
typedef struct cell_info_ind_s {
ci_t cellID; /* Identity of the new serving cell */
tac_t tac; /* Code of the tracking area the cell belongs to */
ci_t cellID; /* Identity of the new serving cell */
tac_t tac; /* Code of the tracking area the cell belongs to */
} cell_info_ind_t;
/*
@@ -260,10 +261,10 @@ typedef struct cell_info_ind_s {
/* Paging cause */
typedef enum paging_cause_s {
AS_CONNECTION_ESTABLISH, /* Establish NAS signalling connection */
AS_EPS_ATTACH, /* Perform local detach and initiate EPS
AS_CONNECTION_ESTABLISH, /* Establish NAS signalling connection */
AS_EPS_ATTACH, /* Perform local detach and initiate EPS
* attach procedure */
AS_CS_FALLBACK /* Inititate CS fallback procedure */
AS_CS_FALLBACK /* Inititate CS fallback procedure */
} paging_cause_t;
/*
@@ -272,8 +273,8 @@ typedef enum paging_cause_s {
* to be sent.
*/
typedef struct paging_req_s {
as_stmsi_t s_tmsi; /* UE identity */
UInt8_t CN_domain; /* Core network domain */
as_stmsi_t s_tmsi; /* UE identity */
uint8_t CN_domain; /* Core network domain */
} paging_req_t;
/*
@@ -281,7 +282,7 @@ typedef struct paging_req_s {
* AS reports to the NAS that appropriate procedure has to be initiated.
*/
typedef struct paging_ind_s {
paging_cause_t cause; /* Paging cause */
paging_cause_t cause; /* Paging cause */
} paging_ind_t;
/*
@@ -292,22 +293,22 @@ typedef struct paging_ind_s {
/* Cause of RRC connection establishment */
typedef enum as_cause_s {
AS_CAUSE_UNKNOWN = 0,
AS_CAUSE_EMERGENCY = NET_ESTABLISH_CAUSE_EMERGENCY,
AS_CAUSE_HIGH_PRIO = NET_ESTABLISH_CAUSE_HIGH_PRIO,
AS_CAUSE_MT_ACCESS = NET_ESTABLISH_CAUSE_MT_ACCESS,
AS_CAUSE_MO_SIGNAL = NET_ESTABLISH_CAUSE_MO_SIGNAL,
AS_CAUSE_MO_DATA = NET_ESTABLISH_CAUSE_MO_DATA,
AS_CAUSE_V1020 = NET_ESTABLISH_CAUSE_V1020
AS_CAUSE_UNKNOWN = 0,
AS_CAUSE_EMERGENCY = NET_ESTABLISH_CAUSE_EMERGENCY,
AS_CAUSE_HIGH_PRIO = NET_ESTABLISH_CAUSE_HIGH_PRIO,
AS_CAUSE_MT_ACCESS = NET_ESTABLISH_CAUSE_MT_ACCESS,
AS_CAUSE_MO_SIGNAL = NET_ESTABLISH_CAUSE_MO_SIGNAL,
AS_CAUSE_MO_DATA = NET_ESTABLISH_CAUSE_MO_DATA,
AS_CAUSE_V1020 = NET_ESTABLISH_CAUSE_V1020
} as_cause_t;
/* Type of the call associated to the RRC connection establishment */
typedef enum as_call_type_s {
AS_TYPE_ORIGINATING_SIGNAL = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL,
AS_TYPE_EMERGENCY_CALLS = NET_ESTABLISH_TYPE_EMERGENCY_CALLS,
AS_TYPE_ORIGINATING_CALLS = NET_ESTABLISH_TYPE_ORIGINATING_CALLS,
AS_TYPE_TERMINATING_CALLS = NET_ESTABLISH_TYPE_TERMINATING_CALLS,
AS_TYPE_MO_CS_FALLBACK = NET_ESTABLISH_TYPE_MO_CS_FALLBACK
AS_TYPE_ORIGINATING_SIGNAL = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL,
AS_TYPE_EMERGENCY_CALLS = NET_ESTABLISH_TYPE_EMERGENCY_CALLS,
AS_TYPE_ORIGINATING_CALLS = NET_ESTABLISH_TYPE_ORIGINATING_CALLS,
AS_TYPE_TERMINATING_CALLS = NET_ESTABLISH_TYPE_TERMINATING_CALLS,
AS_TYPE_MO_CS_FALLBACK = NET_ESTABLISH_TYPE_MO_CS_FALLBACK
} as_call_type_t;
/*
@@ -316,11 +317,11 @@ typedef enum as_call_type_s {
* to transfer initial NAS message to the network while UE is in IDLE mode.
*/
typedef struct nas_establish_req_s {
as_cause_t cause; /* RRC connection establishment cause */
as_call_type_t type; /* RRC associated call type */
as_stmsi_t s_tmsi; /* UE identity */
plmn_t plmnID; /* Selected PLMN identity */
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
as_cause_t cause; /* RRC connection establishment cause */
as_call_type_t type; /* RRC associated call type */
as_stmsi_t s_tmsi; /* UE identity */
plmn_t plmnID; /* Selected PLMN identity */
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
} nas_establish_req_t;
/*
@@ -328,11 +329,11 @@ typedef struct nas_establish_req_s {
* AS transfers the initial NAS message to the NAS.
*/
typedef struct nas_establish_ind_s {
UInt32_t UEid; /* UE lower layer identifier */
tac_t tac; /* Code of the tracking area the initiating
uint32_t UEid; /* UE lower layer identifier */
tac_t tac; /* Code of the tracking area the initiating
* UE belongs to */
as_cause_t asCause; /* Establishment cause */
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
as_cause_t asCause; /* Establishment cause */
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
} nas_establish_ind_t;
/*
@@ -341,13 +342,13 @@ typedef struct nas_establish_ind_s {
* the UE.
*/
typedef struct nas_establish_rsp_s {
UInt32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
nas_error_code_t errCode; /* Transaction status */
as_nas_info_t nasMsg; /* NAS message to transfer */
UInt32_t nas_ul_count; /* UL NAS COUNT */
uint16_t selected_encryption_algorithm;
uint16_t selected_integrity_algorithm;
uint32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
nas_error_code_t errCode; /* Transaction status */
as_nas_info_t nasMsg; /* NAS message to transfer */
uint32_t nas_ul_count; /* UL NAS COUNT */
uint16_t selected_encryption_algorithm;
uint16_t selected_integrity_algorithm;
} nas_establish_rsp_t;
/*
@@ -355,12 +356,12 @@ typedef struct nas_establish_rsp_s {
* AS transfers the initial answer message to the NAS.
*/
typedef struct nas_establish_cnf_s {
UInt32_t UEid; /* UE lower layer identifier */
nas_error_code_t errCode; /* Transaction status */
as_nas_info_t nasMsg; /* NAS message to transfer */
UInt32_t ul_nas_count;
uint16_t selected_encryption_algorithm;
uint16_t selected_integrity_algorithm;
uint32_t UEid; /* UE lower layer identifier */
nas_error_code_t errCode; /* Transaction status */
as_nas_info_t nasMsg; /* NAS message to transfer */
uint32_t ul_nas_count;
uint16_t selected_encryption_algorithm;
uint16_t selected_integrity_algorithm;
} nas_establish_cnf_t;
/*
@@ -371,8 +372,8 @@ typedef struct nas_establish_cnf_s {
/* Release cause */
typedef enum release_cause_s {
AS_AUTHENTICATION_FAILURE = 1, /* Authentication procedure failed */
AS_DETACH /* Detach requested */
AS_AUTHENTICATION_FAILURE = 1, /* Authentication procedure failed */
AS_DETACH /* Detach requested */
} release_cause_t;
/*
@@ -380,9 +381,9 @@ typedef enum release_cause_s {
* NAS requests the termination of the connection with the UE.
*/
typedef struct nas_release_req_s {
UInt32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
release_cause_t cause; /* Release cause */
uint32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
release_cause_t cause; /* Release cause */
} nas_release_req_t;
/*
@@ -390,7 +391,7 @@ typedef struct nas_release_req_s {
* AS reports that connection has been terminated by the network.
*/
typedef struct nas_release_ind_s {
release_cause_t cause; /* Release cause */
release_cause_t cause; /* Release cause */
} nas_release_ind_t;
/*
@@ -405,9 +406,9 @@ typedef struct nas_release_ind_s {
* operates at the network side.
*/
typedef struct ul_info_transfer_req_s {
UInt32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
as_nas_info_t nasMsg; /* Uplink NAS message */
uint32_t UEid; /* UE lower layer identifier */
as_stmsi_t s_tmsi; /* UE identity */
as_nas_info_t nasMsg; /* Uplink NAS message */
} ul_info_transfer_req_t;
/*
@@ -416,8 +417,8 @@ typedef struct ul_info_transfer_req_s {
* successfully sent to the network or not.
*/
typedef struct ul_info_transfer_cnf_s {
UInt32_t UEid; /* UE lower layer identifier */
nas_error_code_t errCode; /* Transaction status */
uint32_t UEid; /* UE lower layer identifier */
nas_error_code_t errCode; /* Transaction status */
} ul_info_transfer_cnf_t;
/*
@@ -426,8 +427,8 @@ typedef struct ul_info_transfer_cnf_s {
* at the network side.
*/
typedef struct ul_info_transfer_ind_s {
UInt32_t UEid; /* UE lower layer identifier */
as_nas_info_t nasMsg; /* Uplink NAS message */
uint32_t UEid; /* UE lower layer identifier */
as_nas_info_t nasMsg; /* Uplink NAS message */
} ul_info_transfer_ind_t;
/*
@@ -466,9 +467,9 @@ typedef struct {} as_qos_t;
* bearer initialized at the network side.
*/
typedef struct rab_establish_req_s {
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
as_qos_t QoS; /* Requested Quality of Service */
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
as_qos_t QoS; /* Requested Quality of Service */
} rab_establish_req_t;
/*
@@ -476,7 +477,7 @@ typedef struct rab_establish_req_s {
* AS notifies the NAS that specific radio access bearer has to be setup.
*/
typedef struct rab_establish_ind_s {
as_rab_id_t rabID; /* Radio access bearer identity */
as_rab_id_t rabID; /* Radio access bearer identity */
} rab_establish_ind_t;
/*
@@ -485,9 +486,9 @@ typedef struct rab_establish_ind_s {
* successfully setup or not.
*/
typedef struct rab_establish_rsp_s {
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
nas_error_code_t errCode; /* Transaction status */
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
nas_error_code_t errCode; /* Transaction status */
} rab_establish_rsp_t;
/*
@@ -496,8 +497,8 @@ typedef struct rab_establish_rsp_s {
* successfully setup at the UE side or not.
*/
typedef struct rab_establish_cnf_s {
as_rab_id_t rabID; /* Radio access bearer identity */
nas_error_code_t errCode; /* Transaction status */
as_rab_id_t rabID; /* Radio access bearer identity */
nas_error_code_t errCode; /* Transaction status */
} rab_establish_cnf_t;
/*
@@ -512,8 +513,8 @@ typedef struct rab_establish_cnf_s {
* to specific radio access bearer at the network side.
*/
typedef struct rab_release_req_s {
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
as_stmsi_t s_tmsi; /* UE identity */
as_rab_id_t rabID; /* Radio access bearer identity */
} rab_release_req_t;
/*
@@ -521,7 +522,7 @@ typedef struct rab_release_req_s {
* AS notifies NAS that specific radio access bearer has been released.
*/
typedef struct rab_release_ind_s {
as_rab_id_t rabID; /* Radio access bearer identity */
as_rab_id_t rabID; /* Radio access bearer identity */
} rab_release_ind_t;
/*
@@ -530,33 +531,33 @@ typedef struct rab_release_ind_s {
* --------------------------------------------------------------------------
*/
typedef struct as_message_s {
UInt16_t msgID;
union {
broadcast_info_ind_t broadcast_info_ind;
cell_info_req_t cell_info_req;
cell_info_cnf_t cell_info_cnf;
cell_info_ind_t cell_info_ind;
paging_req_t paging_req;
paging_ind_t paging_ind;
nas_establish_req_t nas_establish_req;
nas_establish_ind_t nas_establish_ind;
nas_establish_rsp_t nas_establish_rsp;
nas_establish_cnf_t nas_establish_cnf;
nas_release_req_t nas_release_req;
nas_release_ind_t nas_release_ind;
ul_info_transfer_req_t ul_info_transfer_req;
ul_info_transfer_cnf_t ul_info_transfer_cnf;
ul_info_transfer_ind_t ul_info_transfer_ind;
dl_info_transfer_req_t dl_info_transfer_req;
dl_info_transfer_cnf_t dl_info_transfer_cnf;
dl_info_transfer_ind_t dl_info_transfer_ind;
rab_establish_req_t rab_establish_req;
rab_establish_ind_t rab_establish_ind;
rab_establish_rsp_t rab_establish_rsp;
rab_establish_cnf_t rab_establish_cnf;
rab_release_req_t rab_release_req;
rab_release_ind_t rab_release_ind;
} __attribute__((__packed__)) msg;
uint16_t msgID;
union {
broadcast_info_ind_t broadcast_info_ind;
cell_info_req_t cell_info_req;
cell_info_cnf_t cell_info_cnf;
cell_info_ind_t cell_info_ind;
paging_req_t paging_req;
paging_ind_t paging_ind;
nas_establish_req_t nas_establish_req;
nas_establish_ind_t nas_establish_ind;
nas_establish_rsp_t nas_establish_rsp;
nas_establish_cnf_t nas_establish_cnf;
nas_release_req_t nas_release_req;
nas_release_ind_t nas_release_ind;
ul_info_transfer_req_t ul_info_transfer_req;
ul_info_transfer_cnf_t ul_info_transfer_cnf;
ul_info_transfer_ind_t ul_info_transfer_ind;
dl_info_transfer_req_t dl_info_transfer_req;
dl_info_transfer_cnf_t dl_info_transfer_cnf;
dl_info_transfer_ind_t dl_info_transfer_ind;
rab_establish_req_t rab_establish_req;
rab_establish_ind_t rab_establish_ind;
rab_establish_rsp_t rab_establish_rsp;
rab_establish_cnf_t rab_establish_cnf;
rab_release_req_t rab_release_req;
rab_release_ind_t rab_release_ind;
} __attribute__((__packed__)) msg;
} as_message_t;
/****************************************************************************/
@@ -567,11 +568,11 @@ typedef struct as_message_s {
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
int as_message_decode(const char *buffer, as_message_t *msg, int length);
int as_message_decode(const char* buffer, as_message_t* msg, int length);
int as_message_encode(char *buffer, as_message_t *msg, int length);
int as_message_encode(char* buffer, as_message_t* msg, int length);
/* Implemented in the network_api.c body file */
int as_message_send(as_message_t *as_msg);
int as_message_send(as_message_t* as_msg);
#endif /* __AS_MESSAGE_H__*/
+152 -99
View File
@@ -1,31 +1,31 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT OWNER 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.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
/*
Source commonDef.h
@@ -49,6 +49,9 @@ Description Contains global common definitions
#include <stdint.h>
#include <stddef.h>
#define NAS_UE_ID_FMT "0x%06x"
/****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/
/****************************************************************************/
@@ -80,17 +83,8 @@ Description Contains global common definitions
-----------------------------------------------------------------------------
*/
typedef int8_t SByte_t; /* 8 bit signed integer */
typedef int8_t Int8_t; /* 8 bit signed integer */
typedef int16_t Int16_t; /* 16 bit signed integer */
typedef int32_t Int32_t; /* 32 bit signed integer */
typedef int64_t Int64_t; /* 64 bit signed integer */
typedef uint8_t Byte_t; /* 8 bit unsigned integer */
typedef uint8_t UInt8_t; /* 8 bit unsigned integer */
typedef uint16_t UInt16_t; /* 16 bit unsigned integer */
typedef uint32_t UInt32_t; /* 32 bit unsigned integer */
typedef uint64_t UInt64_t; /* 64 bit unsigned integer */
/*
-----------------------------------------------------------------------------
@@ -98,50 +92,76 @@ typedef uint64_t UInt64_t; /* 64 bit unsigned integer */
-----------------------------------------------------------------------------
*/
typedef UInt8_t Stat_t; /* Registration status */
typedef UInt16_t lac_t; /* Location Area Code */
typedef UInt8_t rac_t; /* Routing Area Code */
typedef UInt16_t tac_t; /* Tracking Area Code */
typedef UInt32_t ci_t; /* Cell Identifier */
typedef UInt8_t AcT_t; /* Access Technology */
typedef uint8_t Stat_t; /* Registration status */
typedef uint16_t lac_t; /* Location Area Code */
typedef uint8_t rac_t; /* Routing Area Code */
typedef uint16_t tac_t; /* Tracking Area Code */
typedef uint32_t ci_t; /* Cell Identifier */
typedef uint8_t AcT_t; /* Access Technology */
/*
* International Mobile Subscriber Identity
*/
typedef struct {
Byte_t length;
union {
struct {
Byte_t digit2:4;
Byte_t digit1:4;
Byte_t digit4:4;
Byte_t digit3:4;
Byte_t digit6:4;
Byte_t digit5:4;
Byte_t digit8:4;
Byte_t digit7:4;
Byte_t digit10:4;
Byte_t digit9:4;
Byte_t digit12:4;
Byte_t digit11:4;
Byte_t digit14:4;
Byte_t digit13:4;
Byte_t length;
union {
struct {
Byte_t digit2:4;
Byte_t digit1:4;
Byte_t digit4:4;
Byte_t digit3:4;
Byte_t digit6:4;
Byte_t digit5:4;
Byte_t digit8:4;
Byte_t digit7:4;
Byte_t digit10:4;
Byte_t digit9:4;
Byte_t digit12:4;
Byte_t digit11:4;
Byte_t digit14:4;
Byte_t digit13:4;
#define EVEN_PARITY 0
#define ODD_PARITY 1
Byte_t parity:4;
Byte_t digit15:4;
} num;
Byte_t parity:4;
Byte_t digit15:4;
} num;
#define IMSI_SIZE 8
Byte_t value[IMSI_SIZE];
} u;
Byte_t value[IMSI_SIZE];
} u;
} imsi_t;
#define NAS_IMSI2STR(iMsI_t_PtR,iMsI_sTr, MaXlEn) \
{\
int l_offset = 0;\
int l_ret = 0;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u",\
iMsI_t_PtR->u.num.digit1, iMsI_t_PtR->u.num.digit2,\
iMsI_t_PtR->u.num.digit3, iMsI_t_PtR->u.num.digit4,\
iMsI_t_PtR->u.num.digit5);\
if ((iMsI_t_PtR->u.num.digit6 != 0xf) && (l_ret > 0)) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit6);\
}\
if (l_ret > 0) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u%u%u%u",\
iMsI_t_PtR->u.num.digit7, iMsI_t_PtR->u.num.digit8,\
iMsI_t_PtR->u.num.digit9, iMsI_t_PtR->u.num.digit10,\
iMsI_t_PtR->u.num.digit11, iMsI_t_PtR->u.num.digit12,\
iMsI_t_PtR->u.num.digit13, iMsI_t_PtR->u.num.digit14);\
}\
if ((iMsI_t_PtR->u.num.digit15 != 0xf) && (l_ret > 0)) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit15);\
}\
}
/*
* Mobile subscriber dialing number
*/
typedef struct {
Byte_t ext:1;
/* Type Of Number */
Byte_t ext:1;
/* Type Of Number */
#define MSISDN_TON_UNKNOWKN 0b000
#define MSISDN_TON_INTERNATIONAL 0b001
#define MSISDN_TON_NATIONAL 0b010
@@ -149,8 +169,8 @@ typedef struct {
#define MSISDN_TON_SUBCRIBER 0b100
#define MSISDN_TON_ABBREVIATED 0b110
#define MSISDN_TON_RESERVED 0b111
Byte_t ton:3;
/* Numbering Plan Identification */
Byte_t ton:3;
/* Numbering Plan Identification */
#define MSISDN_NPI_UNKNOWN 0b0000
#define MSISDN_NPI_ISDN_TELEPHONY 0b0001
#define MSISDN_NPI_GENERIC 0b0010
@@ -161,13 +181,13 @@ typedef struct {
#define MSISDN_NPI_ISDN_MOBILE 0b0111
#define MSISDN_NPI_PRIVATE 0b1110
#define MSISDN_NPI_RESERVED 0b1111
Byte_t npi:4;
/* Dialing Number */
struct {
Byte_t lsb:4;
Byte_t msb:4;
Byte_t npi:4;
/* Dialing Number */
struct {
Byte_t lsb:4;
Byte_t msb:4;
#define MSISDN_DIGIT_SIZE 10
} digit[MSISDN_DIGIT_SIZE];
} digit[MSISDN_DIGIT_SIZE];
} msisdn_t;
/*
@@ -180,55 +200,88 @@ typedef imsi_t imei_t;
* PLMN = BCD encoding (Mobile Country Code + Mobile Network Code)
*/
typedef struct {
Byte_t MCCdigit2:4;
Byte_t MCCdigit1:4;
Byte_t MNCdigit3:4;
Byte_t MCCdigit3:4;
Byte_t MNCdigit2:4;
Byte_t MNCdigit1:4;
Byte_t MCCdigit2:4;
Byte_t MCCdigit1:4;
Byte_t MNCdigit3:4;
Byte_t MCCdigit3:4;
Byte_t MNCdigit2:4;
Byte_t MNCdigit1:4;
} plmn_t;
/*
* Location Area Identification
*/
typedef struct {
plmn_t plmn; /* <MCC> + <MNC> */
lac_t lac; /* Location Area Code */
plmn_t plmn; /* <MCC> + <MNC> */
lac_t lac; /* Location Area Code */
} lai_t;
/*
* GPRS Routing Area Identification
*/
typedef struct {
plmn_t plmn; /* <MCC> + <MNC> */
lac_t lac; /* Location Area Code */
rac_t rac; /* Routing Area Code */
plmn_t plmn; /* <MCC> + <MNC> */
lac_t lac; /* Location Area Code */
rac_t rac; /* Routing Area Code */
} RAI_t;
/*
* EPS Tracking Area Identification
*/
typedef struct {
plmn_t plmn; /* <MCC> + <MNC> */
tac_t tac; /* Tracking Area Code */
plmn_t plmn; /* <MCC> + <MNC> */
tac_t tac; /* Tracking Area Code */
} tai_t;
/*
* EPS Globally Unique MME Identity
*/
typedef struct {
plmn_t plmn; /* <MCC> + <MNC> */
UInt16_t MMEgid; /* MME group identifier */
UInt8_t MMEcode; /* MME code */
plmn_t plmn; /* <MCC> + <MNC> */
uint16_t MMEgid; /* MME group identifier */
uint8_t MMEcode; /* MME code */
} gummei_t;
/*
* EPS Globally Unique Temporary UE Identity
*/
typedef struct {
gummei_t gummei; /* Globally Unique MME Identity */
UInt32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */
gummei_t gummei; /* Globally Unique MME Identity */
uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */
} GUTI_t;
#define GUTI2STR(GuTi_PtR, GuTi_StR, MaXlEn) \
{\
int l_offset = 0;\
int l_ret = 0;\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u.",\
GuTi_PtR->gummei.plmn.MCCdigit3 * 100 +\
GuTi_PtR->gummei.plmn.MCCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MCCdigit1);\
if (l_ret > 0) {\
l_offset += l_ret;\
} else {\
l_offset = MaXlEn;\
}\
if (GuTi_PtR->gummei.plmn.MNCdigit1 != 0xf) {\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u|%04x|%02x|%08x",\
GuTi_PtR->gummei.plmn.MNCdigit3 * 100 +\
GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MNCdigit1,\
GuTi_PtR->gummei.MMEgid,\
GuTi_PtR->gummei.MMEcode,\
GuTi_PtR->m_tmsi);\
} else {\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%02u|%04x|%02x|%08x",\
GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MNCdigit1,\
GuTi_PtR->gummei.MMEgid,\
GuTi_PtR->gummei.MMEcode,\
GuTi_PtR->m_tmsi);\
}\
}
/* Checks PLMN validity */
#define PLMN_IS_VALID(plmn) (((plmn).MCCdigit1 & \
@@ -263,14 +316,14 @@ typedef struct {
* EPS Mobility Management sublayer
*/
typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t,
const char *, size_t);
const char*, size_t);
typedef enum eps_protocol_discriminator_e {
/* Protocol discriminator identifier for EPS Mobility Management */
EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7,
/* Protocol discriminator identifier for EPS Mobility Management */
EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7,
/* Protocol discriminator identifier for EPS Session Management */
EPS_SESSION_MANAGEMENT_MESSAGE = 0x2,
/* Protocol discriminator identifier for EPS Session Management */
EPS_SESSION_MANAGEMENT_MESSAGE = 0x2,
} eps_protocol_discriminator_t;
/****************************************************************************/
+1 -3
View File
@@ -21,14 +21,12 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
MESSAGE_DEF(GTPV1U_ENB_CREATE_TUNNEL_REQ, MESSAGE_PRIORITY_MAX, gtpv1u_enb_create_tunnel_req_t, Gtpv1uCreateTunnelReq)
MESSAGE_DEF(GTPV1U_ENB_CREATE_TUNNEL_RESP, MESSAGE_PRIORITY_MAX, gtpv1u_enb_create_tunnel_resp_t, Gtpv1uCreateTunnelResp)
MESSAGE_DEF(GTPV1U_ENB_UPDATE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_update_tunnel_req_t, Gtpv1uUpdateTunnelReq)
MESSAGE_DEF(GTPV1U_ENB_UPDATE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_enb_update_tunnel_resp_t, Gtpv1uUpdateTunnelResp)
MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_delete_tunnel_req_t, Gtpv1uDeleteTunnelReq)
+42 -41
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -30,10 +30,11 @@
#ifndef GTPV1_U_MESSAGES_TYPES_H_
#define GTPV1_U_MESSAGES_TYPES_H_
#include "asn1_constants.h"
#define GTPV1U_MAX_BEARERS_PER_UE max_val_DRB_Identity
#define GTPV1U_ENB_CREATE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uCreateTunnelReq
#define GTPV1U_ENB_CREATE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uCreateTunnelResp
#define GTPV1U_ENB_UPDATE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelReq
#define GTPV1U_ENB_UPDATE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelResp
#define GTPV1U_ENB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDeleteTunnelReq
@@ -44,65 +45,65 @@
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
typedef struct gtpv1u_enb_create_tunnel_req_s {
module_id_t ue_index;
int num_tunnels;
teid_t sgw_S1u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
transport_layer_addr_t sgw_addr[GTPV1U_MAX_BEARERS_PER_UE];
rnti_t rnti;
int num_tunnels;
teid_t sgw_S1u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
transport_layer_addr_t sgw_addr[GTPV1U_MAX_BEARERS_PER_UE];
} gtpv1u_enb_create_tunnel_req_t;
typedef struct gtpv1u_enb_create_tunnel_resp_s {
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
uint8_t ue_index;
int num_tunnels;
teid_t enb_S1u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
transport_layer_addr_t enb_addr;
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
rnti_t rnti;
int num_tunnels;
teid_t enb_S1u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
transport_layer_addr_t enb_addr;
} gtpv1u_enb_create_tunnel_resp_t;
typedef struct gtpv1u_enb_update_tunnel_req_s {
uint8_t ue_index;
teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
transport_layer_addr_t sgw_addr;
ebi_t eps_bearer_id;
rnti_t rnti;
teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
transport_layer_addr_t sgw_addr;
ebi_t eps_bearer_id;
} gtpv1u_enb_update_tunnel_req_t;
typedef struct gtpv1u_enb_update_tunnel_resp_s {
uint8_t ue_index;
uint8_t status; ///< Status (Failed = 0xFF or Success = 0x0)
teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
ebi_t eps_bearer_id;
rnti_t rnti;
uint8_t status; ///< Status (Failed = 0xFF or Success = 0x0)
teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
ebi_t eps_bearer_id;
} gtpv1u_enb_update_tunnel_resp_t;
typedef struct gtpv1u_enb_delete_tunnel_req_s {
module_id_t ue_index;
uint8_t num_erab;
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
//teid_t enb_S1u_teid; ///< local SGW S11 Tunnel Endpoint Identifier
rnti_t rnti;
uint8_t num_erab;
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
//teid_t enb_S1u_teid; ///< local SGW S11 Tunnel Endpoint Identifier
} gtpv1u_enb_delete_tunnel_req_t;
typedef struct gtpv1u_enb_delete_tunnel_resp_s {
uint8_t ue_index;
uint8_t status; ///< Status of S1U endpoint deleteion (Failed = 0xFF or Success = 0x0)
teid_t enb_S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
rnti_t rnti;
uint8_t status; ///< Status of S1U endpoint deleteion (Failed = 0xFF or Success = 0x0)
teid_t enb_S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
} gtpv1u_enb_delete_tunnel_resp_t;
typedef struct gtpv1u_enb_tunnel_data_ind_s {
uint8_t ue_index;
uint8_t *buffer;
uint32_t length;
uint32_t offset; ///< start of message offset in buffer
teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier
rnti_t rnti;
uint8_t *buffer;
uint32_t length;
uint32_t offset; ///< start of message offset in buffer
teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier
} gtpv1u_enb_tunnel_data_ind_t;
typedef struct gtpv1u_enb_tunnel_data_req_s {
uint8_t *buffer;
uint32_t length;
uint32_t offset; ///< start of message offset in buffer
uint8_t ue_index;
rb_id_t rab_id;
uint8_t *buffer;
uint32_t length;
uint32_t offset; ///< start of message offset in buffer
rnti_t rnti;
rb_id_t rab_id;
} gtpv1u_enb_tunnel_data_req_t;
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+14 -8
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -53,14 +53,15 @@
#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind
// Some constants from "LAYER2/MAC/defs.h"
#define BCCH_SDU_SIZE (128)
#define CCCH_SDU_SIZE (128)
#define MCCH_SDU_SIZE (128)
#define BCCH_SDU_SIZE (512)
#define CCCH_SDU_SIZE (512)
#define MCCH_SDU_SIZE (512)
//-------------------------------------------------------------------------------------------//
// Messages between RRC and MAC layers
typedef struct RrcMacInSyncInd_s {
uint32_t frame;
uint8_t sub_frame;
uint16_t enb_index;
} RrcMacInSyncInd;
@@ -75,6 +76,7 @@ typedef struct RrcMacBcchDataReq_s {
typedef struct RrcMacBcchDataInd_s {
uint32_t frame;
uint8_t sub_frame;
uint32_t sdu_size;
uint8_t sdu[BCCH_SDU_SIZE];
uint8_t enb_index;
@@ -94,10 +96,13 @@ typedef struct RrcMacCcchDataCnf_s {
} RrcMacCcchDataCnf;
typedef struct RrcMacCcchDataInd_s {
uint32_t frame;
uint32_t sdu_size;
uint8_t sdu[CCCH_SDU_SIZE];
uint8_t enb_index;
uint32_t frame;
uint8_t sub_frame;
uint16_t rnti;
uint32_t sdu_size;
uint8_t sdu[CCCH_SDU_SIZE];
uint8_t enb_index;
int CC_id;
} RrcMacCcchDataInd;
typedef struct RrcMacMcchDataReq_s {
@@ -110,6 +115,7 @@ typedef struct RrcMacMcchDataReq_s {
typedef struct RrcMacMcchDataInd_s {
uint32_t frame;
uint8_t sub_frame;
uint32_t sdu_size;
uint8_t sdu[MCCH_SDU_SIZE];
uint8_t enb_index;
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+9 -8
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -75,7 +75,7 @@ in a suspended state or to indicate the current buffer occupancy to MAC.
// primitives definition
//----------------------------------------------------------
# define UE_ID_TYPE_U_RNTI 0xFF
// should not be used ?
// should not be used ?
# define UE_ID_TYPE_C_RNTI 0xCC
# define MAC_TX_STATUS_SUCCESSFUL 0x0F
@@ -192,9 +192,10 @@ that RLC would use this primitive to indicate that it has nothing to send or tha
in a suspended state or to indicate the current buffer occupancy to MAC.
*/
struct mac_status_resp {
unsigned int buffer_occupancy_in_bytes; /*!< \brief the parameter Buffer Occupancy (BO) indicates for each logical channel the amount of data in number of bytes that is available for transmission and retransmission in RLC layer. */
unsigned int
buffer_occupancy_in_bytes; /*!< \brief the parameter Buffer Occupancy (BO) indicates for each logical channel the amount of data in number of bytes that is available for transmission and retransmission in RLC layer. */
unsigned short buffer_occupancy_in_pdus; /*!< xxx*/
uint32_t head_sdu_creation_time;
uint32_t head_sdu_creation_time;
uint32_t head_sdu_remaining_size_to_send;
unsigned char head_sdu_is_segmented;
struct rlc_entity_info rlc_info; /*!< xxx*/
@@ -224,11 +225,11 @@ struct mac_data_req {
transmitted but not negatively acknowledged by the peer entity shall not be included in the BO.*/
unsigned short buffer_occupancy_in_pdus; /*!< xxx*/
struct rlc_entity_info rlc_info; /*!< indicates to MAC the configuration parameters that are critical to TFC selection depending
on its mode and the amount of data that could be transmitted at the next TTI. This primitive
is meant to insure that MAC can perform TFC selection.*/
on its mode and the amount of data that could be transmitted at the next TTI. This primitive
is meant to insure that MAC can perform TFC selection.*/
unsigned char ue_id_type_indicator; /*!< indicates the UE-ID type to be included in MAC for a DCCH when it is mapped onto a common
transport channel (i.e. FACH, RACH, DSCH in FDD or CPCH). On the UE side UE-ID Type Indicator
shall always be set to C-RNTI.*/
transport channel (i.e. FACH, RACH, DSCH in FDD or CPCH). On the UE side UE-ID Type Indicator
shall always be set to C-RNTI.*/
};
//---------------------
/*! \brief MAC-DATA-Ind primitive indicates the arrival of upper layer PDUs received within one
+63 -62
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -111,36 +111,36 @@ typedef enum {
/*! MAC/PHY Measurement Structure*/
/*! \brief Logical Channel ID structure */
typedef struct{
typedef struct {
unsigned short Index __attribute__ ((packed)); //QOS CLASS? /*!< \brief Index of logical channel*/
}LCHAN_ID;
} LCHAN_ID;
typedef struct{
typedef struct {
char Rssi; /*!< \brief RSSI (dBm) on physical resources corresponding to logical channel*/
char Sinr[NUMBER_OF_MEASUREMENT_SUBBANDS]; /*!< \brief Average SINR (dB) on physical resources corresponding to logical channel*/
uint8_t Harq_delay; /*!< \brief Average number of transmission rounds (times 10) on transport channel associated with
logical channel*/
logical channel*/
unsigned short Bler; /*!< \brief Average block error rate (times 1000) on transport channel associated with logical channel*/
uint8_t Spec_eff; /*!< \brief Actual Spectral efficiency (bits/symbol times 10) of transport channel associated with logical channel*/
uint8_t Qdepth;
//uint8_t Tx_rate;
//uint8_t Rx_rate;
}__attribute__ ((__packed__)) MAC_MEAS_T;
uint8_t Qdepth;
//uint8_t Tx_rate;
//uint8_t Rx_rate;
} __attribute__ ((__packed__)) MAC_MEAS_T;
#define MAC_MEAS_T_SIZE sizeof(MAC_MEAS_T)
/*!\brief MAC/RLC Measurement Information
*/
typedef struct{
typedef struct {
char Rssi; /*!< \brief RSSI (dBm) on physical resources corresponding to logical channel*/
char Sinr[NUMBER_OF_MEASUREMENT_SUBBANDS]; /*!< \brief Average SINR (dB) on physical resources corresponding to logical channel*/
uint8_t Harq_delay; /*!< \brief Average number of transmission rounds (times 10) on transport channel associated with
logical channel*/
logical channel*/
unsigned short Bler; /*!< \brief Average block error rate (times 1000) on transport channel associated with logical channel*/
uint8_t Spec_eff; /*!< \brief Actual Spectral efficiency (bits/symbol times 10) of transport channel associated with logical channel*/
uint8_t rlc_sdu_buffer_occ; /*!< \brief RLC SDU buffer occupancy */
unsigned short rlc_sdu_loss_indicator; /*!< \brief RLC SDU Loss indicator */
}__attribute__ ((__packed__)) MAC_RLC_MEAS_T;
} __attribute__ ((__packed__)) MAC_RLC_MEAS_T;
#define MAC_RLC_MEAS_T_SIZE sizeof(MAC_RLC_MEAS_T)
@@ -150,12 +150,12 @@ typedef struct{
/*! MAC/PHY Measurement Averaging Parameters. These are fixed-point 16-bit representations of the interval [0,1)*/
typedef struct {
unsigned short Rssi_forgetting_factor; /*!< \brief Forgetting factor for RSSI averaging*/
unsigned short Sinr_forgetting_factor; /*!< \brief Forgetting factor for SINR averaging*/
unsigned short Harq_delay_forgetting_factor; /*!< \brief Forgetting factor for HARQ delay averaging*/
unsigned short Bler_forgetting_factor; /*!< \brief Forgetting factor for block error rate (times 1000) averaging*/
unsigned short Spec_eff_forgetting_factor; /*!< \brief Forgetting factor for Spectral efficiency averaging*/
}__attribute__ ((__packed__)) MAC_AVG_T;
unsigned short Rssi_forgetting_factor; /*!< \brief Forgetting factor for RSSI averaging*/
unsigned short Sinr_forgetting_factor; /*!< \brief Forgetting factor for SINR averaging*/
unsigned short Harq_delay_forgetting_factor; /*!< \brief Forgetting factor for HARQ delay averaging*/
unsigned short Bler_forgetting_factor; /*!< \brief Forgetting factor for block error rate (times 1000) averaging*/
unsigned short Spec_eff_forgetting_factor; /*!< \brief Forgetting factor for Spectral efficiency averaging*/
} __attribute__ ((__packed__)) MAC_AVG_T;
/*!\brief This primitive indicates to RRC that a measurement request is available */
@@ -164,7 +164,7 @@ typedef struct {
unsigned short Process_id; /*!< \brief Id of MAC measurement process*/
MAC_MEAS_T Meas;
char Meas_status; /*!< \brief Latest set of MAC measurements performed in the current process*/
}__attribute__ ((__packed__)) MAC_MEAS_IND;
} __attribute__ ((__packed__)) MAC_MEAS_IND;
#define MAC_MEAS_IND_SIZE sizeof(MAC_MEAS_IND)
@@ -174,7 +174,7 @@ typedef struct {
//LCHAN_ID Lchan_id; /*!< \brief Logical Channel ID*/
//unsigned short Process_id; /*!< \brief Id of new MAC measurement process*/
char Meas_status; /*!< \brief Status (0-positive, 1-negative)*/
}__attribute__ ((__packed__)) MAC_MEAS_CONFIRM;
} __attribute__ ((__packed__)) MAC_MEAS_CONFIRM;
/*!\brief This primitive parametrizes a MAC measurement process
*/
@@ -185,7 +185,7 @@ typedef struct {
unsigned int sdu_loss_trigger; /*!< \brief Trigger for RLC SDU losses*/
unsigned short Rep_amount; /*!< \brief Number of Measurements for this process, 0 means infinite*/
unsigned short Rep_interval; /*!< \brief Reporting interval between successive measurement reports in this process*/
}__attribute__ ((__packed__)) MAC_RLC_MEAS_DESC;
} __attribute__ ((__packed__)) MAC_RLC_MEAS_DESC;
@@ -201,10 +201,10 @@ typedef struct {
unsigned short Rep_amount; /*!< \brief Number of Measurements for this process, 0 means infinite*/
unsigned short Rep_interval; /*!< \brief Reporting interval between successive measurement reports in this process*/
MAC_MEAS_T Mac_meas; /*!< \brief Measure structure to be filled by the MAC */
}__attribute__ ((__packed__)) MAC_MEAS_REQ;
} __attribute__ ((__packed__)) MAC_MEAS_REQ;
#define MAC_MEAS_REQ_SIZE sizeof(MAC_MEAS_REQ)
typedef struct MEAS_REQ_TABLE_ENTRY{
typedef struct MEAS_REQ_TABLE_ENTRY {
MAC_MEAS_REQ Mac_meas_req;
unsigned int Last_report_frame;
unsigned int Next_check_frame;
@@ -214,15 +214,15 @@ typedef struct MEAS_REQ_TABLE_ENTRY{
//uint8_t Meas_Direction;//???
struct MEAS_REQ_TABLE_ENTRY *Next_entry;
struct MEAS_REQ_TABLE_ENTRY *Prev_entry;
}__attribute__ ((__packed__)) MAC_MEAS_REQ_ENTRY;
} __attribute__ ((__packed__)) MAC_MEAS_REQ_ENTRY;
/*!\brief This primitive parametrizes an RLC measurement process
*/
typedef struct{
typedef struct {
unsigned int bo_forgetting_factor; /*!< \brief Forgetting factor for buffer occupancy averaging*/
unsigned int sdu_loss_trigger; /*!< \brief Trigger for RLC sdu losses*/
}__attribute__ ((__packed__)) RLC_MEAS_DESC;
} __attribute__ ((__packed__)) RLC_MEAS_DESC;
//#define NUM_MEAS_REQ_MAX 100 //from rrm
@@ -241,7 +241,7 @@ typedef struct {
uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/
uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/
uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/
}__attribute__ ((__packed__)) LCHAN_DESC;
} __attribute__ ((__packed__)) LCHAN_DESC;
#define LCHAN_DESC_SIZE sizeof(LCHAN_DESC)
@@ -262,17 +262,17 @@ typedef struct MAC_OUT_OF_SYNC {
/*!\brief This primitive enables RRC to configure a new logical channel description at the MAC layer.
*/
typedef struct{
typedef struct {
LCHAN_ID Lchan_id; /*!< \brief Logical Channel ID*/
// unsigned short UE_eNB_index; //ID of CH who configued the LC (Need this to identify LC in the UE side)
uint8_t Lchan_type; // DCCH_LCHAN, DTCH_LCHAN
LCHAN_DESC Lchan_desc[2]; /*!< \brief Logical Channel QoS Descriptor (MAC component) */
uint8_t L3_info_type;
uint8_t L3_info[16];
//#ifndef CELLULAR
unsigned short UE_eNB_index;
//#endif
}__attribute__ ((__packed__)) MAC_CONFIG_REQ;
LCHAN_DESC Lchan_desc[2]; /*!< \brief Logical Channel QoS Descriptor (MAC component) */
uint8_t L3_info_type;
uint8_t L3_info[16];
//#ifndef CELLULAR
unsigned short UE_eNB_index;
//#endif
} __attribute__ ((__packed__)) MAC_CONFIG_REQ;
#define MAC_CONFIG_REQ_SIZE sizeof(MAC_CONFIG_REQ)
@@ -281,7 +281,7 @@ typedef struct{
typedef struct {
LCHAN_ID Lchan_id; /*!< \brief Logical Channel ID*/
uint8_t Config_status; /*!< \brief Configuration status (0-positive, 1-negative)*/
}__attribute__ ((__packed__)) MAC_CONFIG_CONFIRM;
} __attribute__ ((__packed__)) MAC_CONFIG_CONFIRM;
/**@}*/
@@ -304,21 +304,21 @@ typedef struct {
unsigned int Last_report_frame;
unsigned int Next_check_frame;
uint8_t Active;
}__attribute__ ((__packed__)) DEFAULT_UE_MEAS;
} __attribute__ ((__packed__)) DEFAULT_UE_MEAS;
#define DEFAULT_UE_MEAS_SIZE sizeof(DEFAULT_UE_MEAS)
typedef struct { //From RRC
unsigned short UE_index;
uint8_t Forg_fact;
unsigned short Rep_interval;;
}__attribute__ ((__packed__)) DEFAULT_MEAS_REQ;
} __attribute__ ((__packed__)) DEFAULT_MEAS_REQ;
#define DEFAULT_MEAS_REQ_SIZE sizeof(DEFAULT_MEAS_REQ)
typedef struct { //To RRC
unsigned short UE_index __attribute__ ((packed));
char Sinr_meas[NB_CNX_CH+1];
uint8_t Rb_active[NB_RAB_MAX];
}__attribute__ ((__packed__)) DEFAULT_MEAS_IND;
} __attribute__ ((__packed__)) DEFAULT_MEAS_IND;
#define DEFAULT_MEAS_IND_SIZE sizeof(DEFAULT_MEAS_IND)
@@ -332,7 +332,7 @@ typedef struct {
unsigned int Next_check_frame;
uint8_t Status; //IDLE,NEED_rADIO_CONFIG, RADIO_CONFIG_TX, RADIO_CONFIG_ok
uint8_t Active;
}__attribute__ ((__packed__)) DEFAULT_CH_MEAS;
} __attribute__ ((__packed__)) DEFAULT_CH_MEAS;
#define DEFAULT_eNB_MEAS_SIZE sizeof(DEFAULT_eNB_MEAS)
@@ -343,7 +343,7 @@ typedef struct {
//#include "L3_rrc_defs.h"
#endif
typedef struct{ //RRC_INTERFACE_FUNCTIONS
typedef struct { //RRC_INTERFACE_FUNCTIONS
unsigned int Frame_index;
unsigned short UE_index[NB_MODULES_MAX][NB_SIG_CNX_UE];
uint8_t eNB_id[NB_MODULES_MAX][NB_CNX_UE];
@@ -363,10 +363,10 @@ typedef struct{ //RRC_INTERFACE_FUNCTIONS
void (*fn_rrc) (void);
uint8_t (*get_rrc_status)(uint8_t Mod_id,uint8_t eNB_flag,uint8_t eNB_index);
double (*rrc_get_estimated_ue_distance) (module_id_t Mod_id, uint8_t UE_id, uint8_t CC_id, uint8_t loc_type);
}RRC_XFACE;
} RRC_XFACE;
typedef struct{
typedef struct {
//MAC_INTERFACE_FUNCTIONS
unsigned int frame;
unsigned short Node_id[NB_MODULES_MAX];
@@ -380,32 +380,33 @@ typedef struct{
void (*pdcp_data_req)(module_id_t, rb_id_t, sdu_size_t, char*);
signed int (*rrc_rlc_config_req)(unsigned int, unsigned int, unsigned int, unsigned int, rlc_info_t );
int (*rrc_mac_config_req)(uint8_t Mod_id,uint8_t eNB_flag,uint8_t UE_id,uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig,
MeasGapConfig_t *measGapConfig,
TDD_Config_t *tdd_Config,
uint8_t *SIwindowsize,
uint16_t *SIperiod
#ifdef Rel10
,
MBMS_flag_t MBMS_Flag,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList,
struct PMCH_InfoList_r9 *pmch_InfoList
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig,
MeasGapConfig_t *measGapConfig,
TDD_Config_t *tdd_Config,
uint8_t *SIwindowsize,
uint16_t *SIperiod
#ifdef Rel10
,
MBMS_flag_t MBMS_Flag,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList,
struct PMCH_InfoList_r9 *pmch_InfoList
#endif
);
);
unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, char*);
void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* );
mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, logical_chan_id_t channel_idP, tb_size_t tb_sizeP);
mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP,
logical_chan_id_t channel_idP, tb_size_t tb_sizeP);
signed int (*rrc_rlc_data_req)(module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, char *);
void (*rrc_rlc_register_rrc) (void (*rrc_data_indP)(module_id_t , rb_id_t , sdu_size_t , char* ),
void (*rrc_data_confP) (module_id_t , rb_id_t , mui_t ) ) ;
void (*rrc_data_confP) (module_id_t , rb_id_t , mui_t ) ) ;
void (*mrbch_phy_sync_failure) (uint8_t Mod_id, frame_t frame, uint8_t Free_ch_index);
void (*dl_phy_sync_success) (uint8_t Mod_id, frame_t frame, uint8_t eNB_index);
}MAC_RLC_XFACE;
} MAC_RLC_XFACE;
#endif
+3 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -38,7 +38,9 @@
#include "pdcp_messages_def.h"
#include "rrc_messages_def.h"
#include "nas_messages_def.h"
#if ENABLE_RAL
#include "ral_messages_def.h"
#endif
#include "s1ap_messages_def.h"
#include "x2ap_messages_def.h"
#include "sctp_messages_def.h"
+3 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -46,7 +46,9 @@
#include "pdcp_messages_types.h"
#include "rrc_messages_types.h"
#include "nas_messages_types.h"
#if ENABLE_RAL
#include "ral_messages_types.h"
#endif
#include "s1ap_messages_types.h"
#include "x2ap_messages_types.h"
#include "sctp_messages_types.h"
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+66 -66
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -63,91 +63,91 @@
#define NAS_DATA_LENGHT_MAX 256
typedef enum {
EMM_MSG_HEADER = 1,
EMM_MSG_ATTACH_REQUEST,
EMM_MSG_ATTACH_ACCEPT,
EMM_MSG_ATTACH_COMPLETE,
EMM_MSG_ATTACH_REJECT,
EMM_MSG_DETACH_REQUEST,
EMM_MSG_DETACH_ACCEPT,
EMM_MSG_TRACKING_AREA_UPDATE_REQUEST,
EMM_MSG_TRACKING_AREA_UPDATE_ACCEPT,
EMM_MSG_TRACKING_AREA_UPDATE_COMPLETE,
EMM_MSG_TRACKING_AREA_UPDATE_REJECT,
EMM_MSG_EXTENDED_SERVICE_REQUEST,
EMM_MSG_SERVICE_REQUEST,
EMM_MSG_SERVICE_REJECT,
EMM_MSG_GUTI_REALLOCATION_COMMAND,
EMM_MSG_GUTI_REALLOCATION_COMPLETE,
EMM_MSG_AUTHENTICATION_REQUEST,
EMM_MSG_AUTHENTICATION_RESPONSE,
EMM_MSG_AUTHENTICATION_REJECT,
EMM_MSG_AUTHENTICATION_FAILURE,
EMM_MSG_IDENTITY_REQUEST,
EMM_MSG_IDENTITY_RESPONSE,
EMM_MSG_SECURITY_MODE_COMMAND,
EMM_MSG_SECURITY_MODE_COMPLETE,
EMM_MSG_SECURITY_MODE_REJECT,
EMM_MSG_EMM_STATUS,
EMM_MSG_EMM_INFORMATION,
EMM_MSG_DOWNLINK_NAS_TRANSPORT,
EMM_MSG_UPLINK_NAS_TRANSPORT,
EMM_MSG_CS_SERVICE_NOTIFICATION,
EMM_MSG_HEADER = 1,
EMM_MSG_ATTACH_REQUEST,
EMM_MSG_ATTACH_ACCEPT,
EMM_MSG_ATTACH_COMPLETE,
EMM_MSG_ATTACH_REJECT,
EMM_MSG_DETACH_REQUEST,
EMM_MSG_DETACH_ACCEPT,
EMM_MSG_TRACKING_AREA_UPDATE_REQUEST,
EMM_MSG_TRACKING_AREA_UPDATE_ACCEPT,
EMM_MSG_TRACKING_AREA_UPDATE_COMPLETE,
EMM_MSG_TRACKING_AREA_UPDATE_REJECT,
EMM_MSG_EXTENDED_SERVICE_REQUEST,
EMM_MSG_SERVICE_REQUEST,
EMM_MSG_SERVICE_REJECT,
EMM_MSG_GUTI_REALLOCATION_COMMAND,
EMM_MSG_GUTI_REALLOCATION_COMPLETE,
EMM_MSG_AUTHENTICATION_REQUEST,
EMM_MSG_AUTHENTICATION_RESPONSE,
EMM_MSG_AUTHENTICATION_REJECT,
EMM_MSG_AUTHENTICATION_FAILURE,
EMM_MSG_IDENTITY_REQUEST,
EMM_MSG_IDENTITY_RESPONSE,
EMM_MSG_SECURITY_MODE_COMMAND,
EMM_MSG_SECURITY_MODE_COMPLETE,
EMM_MSG_SECURITY_MODE_REJECT,
EMM_MSG_EMM_STATUS,
EMM_MSG_EMM_INFORMATION,
EMM_MSG_DOWNLINK_NAS_TRANSPORT,
EMM_MSG_UPLINK_NAS_TRANSPORT,
EMM_MSG_CS_SERVICE_NOTIFICATION,
} emm_message_ids_t;
typedef enum {
ESM_MSG_HEADER = 1,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_PDN_CONNECTIVITY_REQUEST,
ESM_MSG_PDN_CONNECTIVITY_REJECT,
ESM_MSG_PDN_DISCONNECT_REQUEST,
ESM_MSG_PDN_DISCONNECT_REJECT,
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REQUEST,
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REJECT,
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REQUEST,
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REJECT,
ESM_MSG_ESM_INFORMATION_REQUEST,
ESM_MSG_ESM_INFORMATION_RESPONSE,
ESM_MSG_ESM_STATUS,
ESM_MSG_HEADER = 1,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REJECT,
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST,
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT,
ESM_MSG_PDN_CONNECTIVITY_REQUEST,
ESM_MSG_PDN_CONNECTIVITY_REJECT,
ESM_MSG_PDN_DISCONNECT_REQUEST,
ESM_MSG_PDN_DISCONNECT_REJECT,
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REQUEST,
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REJECT,
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REQUEST,
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REJECT,
ESM_MSG_ESM_INFORMATION_REQUEST,
ESM_MSG_ESM_INFORMATION_RESPONSE,
ESM_MSG_ESM_STATUS,
} esm_message_ids_t;
typedef struct nas_raw_msg_s {
uint32_t lenght;
uint8_t data[NAS_DATA_LENGHT_MAX];
uint32_t lenght;
uint8_t data[NAS_DATA_LENGHT_MAX];
} nas_raw_msg_t;
typedef struct nas_emm_plain_msg_s {
emm_message_ids_t present;
EMM_msg choice;
emm_message_ids_t present;
EMM_msg choice;
} nas_emm_plain_msg_t;
typedef struct nas_emm_protected_msg_s {
nas_message_security_header_t header;
emm_message_ids_t present;
EMM_msg choice;
nas_message_security_header_t header;
emm_message_ids_t present;
EMM_msg choice;
} nas_emm_protected_msg_t;
typedef struct nas_esm_plain_msg_s {
esm_message_ids_t present;
ESM_msg choice;
esm_message_ids_t present;
ESM_msg choice;
} nas_esm_plain_msg_t;
typedef struct nas_esm_protected_msg_s {
nas_message_security_header_t header;
esm_message_ids_t present;
ESM_msg choice;
nas_message_security_header_t header;
esm_message_ids_t present;
ESM_msg choice;
} nas_esm_protected_msg_t;
# endif /* ENABLE_USE_MME */
+67 -67
View File
@@ -1,31 +1,31 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT OWNER 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.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
/*****************************************************************************
@@ -162,14 +162,14 @@ Description Contains network's global definitions
* ---------------------
*/
typedef enum {
/* MT = The Mobile Terminal, NW = The Network */
NET_PDN_MT_DEFAULT_ACT = 1, /* MT has activated a PDN connection */
NET_PDN_NW_DEFAULT_DEACT, /* NW has deactivated a PDN connection */
NET_PDN_MT_DEFAULT_DEACT, /* MT has deactivated a PDN connection */
NET_PDN_NW_DEDICATED_ACT, /* NW has activated an EPS bearer context */
NET_PDN_MT_DEDICATED_ACT, /* MT has activated an EPS bearer context */
NET_PDN_NW_DEDICATED_DEACT, /* NW has deactivated an EPS bearer context */
NET_PDN_MT_DEDICATED_DEACT, /* MT has deactivated an EPS bearer context */
/* MT = The Mobile Terminal, NW = The Network */
NET_PDN_MT_DEFAULT_ACT = 1, /* MT has activated a PDN connection */
NET_PDN_NW_DEFAULT_DEACT, /* NW has deactivated a PDN connection */
NET_PDN_MT_DEFAULT_DEACT, /* MT has deactivated a PDN connection */
NET_PDN_NW_DEDICATED_ACT, /* NW has activated an EPS bearer context */
NET_PDN_MT_DEDICATED_ACT, /* MT has activated an EPS bearer context */
NET_PDN_NW_DEDICATED_DEACT, /* NW has deactivated an EPS bearer context */
NET_PDN_MT_DEDICATED_DEACT, /* MT has deactivated an EPS bearer context */
} network_pdn_state_t;
/*
@@ -181,11 +181,11 @@ typedef struct {
#define NET_FORMAT_LONG_SIZE 16 /* Long alphanumeric format */
#define NET_FORMAT_SHORT_SIZE 8 /* Short alphanumeric format */
#define NET_FORMAT_NUM_SIZE 6 /* Numeric format (PLMN identifier */
union {
unsigned char alpha_long[NET_FORMAT_LONG_SIZE+1];
unsigned char alpha_short[NET_FORMAT_SHORT_SIZE+1];
unsigned char num[NET_FORMAT_NUM_SIZE+1];
} id;
union {
unsigned char alpha_long[NET_FORMAT_LONG_SIZE+1];
unsigned char alpha_short[NET_FORMAT_SHORT_SIZE+1];
unsigned char num[NET_FORMAT_NUM_SIZE+1];
} id;
} network_plmn_t;
/*
@@ -194,11 +194,11 @@ typedef struct {
* -------------------------------
*/
typedef struct {
int gbrUL; /* Guaranteed Bit Rate for uplink */
int gbrDL; /* Guaranteed Bit Rate for downlink */
int mbrUL; /* Maximum Bit Rate for uplink */
int mbrDL; /* Maximum Bit Rate for downlink */
int qci; /* QoS Class Identifier */
int gbrUL; /* Guaranteed Bit Rate for uplink */
int gbrDL; /* Guaranteed Bit Rate for downlink */
int mbrUL; /* Maximum Bit Rate for uplink */
int mbrDL; /* Maximum Bit Rate for downlink */
int qci; /* QoS Class Identifier */
} network_qos_t;
/*
@@ -207,11 +207,11 @@ typedef struct {
* -----------------------------
*/
typedef struct {
unsigned char protocol; /* Protocol identifier */
unsigned char tos; /* Type of service */
unsigned char protocol; /* Protocol identifier */
unsigned char tos; /* Type of service */
#define NET_PACKET_FILTER_IPV4_ADDR_SIZE 4
unsigned char addr[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
unsigned char mask[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
unsigned char addr[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
unsigned char mask[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
} network_ipv4_data_t;
/*
@@ -220,13 +220,13 @@ typedef struct {
* -----------------------------
*/
typedef struct {
unsigned char nh; /* Next header type */
unsigned char tf; /* Traffic class */
unsigned char nh; /* Next header type */
unsigned char tf; /* Traffic class */
#define NET_PACKET_FILTER_IPV6_ADDR_SIZE 16
unsigned char addr[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
unsigned char mask[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
unsigned int ipsec; /* IPSec security parameter index */
unsigned int fl; /* Flow label */
unsigned char addr[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
unsigned char mask[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
unsigned int ipsec; /* IPSec security parameter index */
unsigned int fl; /* Flow label */
} network_ipv6_data_t;
/*
@@ -235,18 +235,18 @@ typedef struct {
* -------------
*/
typedef struct {
unsigned char id; /* Packet filter identifier */
unsigned char id; /* Packet filter identifier */
#define NET_PACKET_FILTER_DOWNLINK 0x01
#define NET_PACKET_FILTER_UPLINK 0x02
#define NET_PACKET_FILTER_BIDIR 0x03
unsigned char dir; /* Packet filter direction */
unsigned char precedence; /* Evaluation precedence */
union {
network_ipv4_data_t ipv4;
network_ipv6_data_t ipv6;
} data;
unsigned short lport; /* Local (UE) port number */
unsigned short rport; /* Remote (network) port number */
unsigned char dir; /* Packet filter direction */
unsigned char precedence; /* Evaluation precedence */
union {
network_ipv4_data_t ipv4;
network_ipv6_data_t ipv6;
} data;
unsigned short lport; /* Local (UE) port number */
unsigned short rport; /* Remote (network) port number */
} network_pkf_t;
/*
@@ -255,9 +255,9 @@ typedef struct {
* ---------------------
*/
typedef struct {
int n_pkfs;
int n_pkfs;
#define NET_PACKET_FILTER_MAX 16
network_pkf_t *pkf[NET_PACKET_FILTER_MAX];
network_pkf_t* pkf[NET_PACKET_FILTER_MAX];
} network_tft_t;
/*
+4 -4
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -34,7 +34,7 @@
#include <linux/kernel.h>
#endif //USER_MODE
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
@@ -61,9 +61,9 @@
#define bigmalloc16(x) (bigphys_malloc(x))
#define malloc16(x) (bigphys_malloc(x))
#define free16(y,x)
#define free16(y,x)
#define bigfree(y,x)
#define bigfree(y,x)
#else // BIGPHYSAREA
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+6 -4
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -53,7 +53,8 @@ typedef struct RrcDcchDataReq_s {
uint32_t sdu_size;
uint8_t *sdu_p;
uint8_t mode;
uint8_t ue_index;
uint16_t rnti;
uint8_t module_id;
uint8_t eNB_index;
} RrcDcchDataReq;
@@ -62,8 +63,9 @@ typedef struct RrcDcchDataInd_s {
uint8_t dcch_index;
uint32_t sdu_size;
uint8_t *sdu_p;
uint8_t ue_index;
uint8_t eNB_index;
uint16_t rnti;
uint8_t module_id;
uint8_t eNB_index; // LG: needed in UE
} RrcDcchDataInd;
#endif /* PDCP_MESSAGES_TYPES_H_ */
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+33 -25
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -38,7 +38,9 @@
#define PHY_MESSAGES_TYPES_H_
#include "PHY/impl_defs_lte.h"
#include "ral_messages_types.h"
#if ENABLE_RAL
#include "ral_messages_types.h" //LG: MIH moved from repository/trunk to repository/extras
#endif
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define PHY_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.phy_configuration_req
@@ -69,10 +71,10 @@ typedef int8_t Rsrp;
typedef int8_t Rsrq;
typedef struct CellInfo_s {
Earfcn earfcn;
PhyCellId cell_id;
Rsrp rsrp;
Rsrq rsrq;
Earfcn earfcn;
PhyCellId cell_id;
Rsrp rsrp;
Rsrq rsrq;
} CellInfo;
//-------------------------------------------------------------------------------------------//
@@ -93,39 +95,45 @@ typedef struct PhyDeactivateReq_s {
} PhyDeactivateReq;
typedef struct PhyFindCellReq_s {
//# if defined(ENABLE_RAL)
ral_transaction_id_t transaction_id;
//# endif
Earfcn earfcn_start;
Earfcn earfcn_end;
# if ENABLE_RAL
ral_transaction_id_t transaction_id;
# endif
Earfcn earfcn_start;
Earfcn earfcn_end;
} PhyFindCellReq;
typedef struct PhyFindNextCellReq_s {
} PhyFindNextCellReq;
typedef struct PhyMeasThresholdReq_s {
ral_transaction_id_t transaction_id;
ral_link_cfg_param_t cfg_param;
# if ENABLE_RAL
ral_transaction_id_t transaction_id;
ral_link_cfg_param_t cfg_param;
#endif
} PhyMeasThresholdReq;
typedef struct PhyMeasReportInd_s {
ral_threshold_t threshold;
ral_link_param_t link_param;
# if ENABLE_RAL
ral_threshold_t threshold;
ral_link_param_t link_param;
#endif
} PhyMeasReportInd;
// UE: PHY -> RRC messages
typedef struct PhyFindCellInd_s {
//# if defined(ENABLE_RAL)
ral_transaction_id_t transaction_id;
//# endif
uint8_t cell_nb;
CellInfo cells[MAX_REPORTED_CELL];
# if ENABLE_RAL
ral_transaction_id_t transaction_id;
# endif
uint8_t cell_nb;
CellInfo cells[MAX_REPORTED_CELL];
} PhyFindCellInd;
typedef struct PhyMeasThresholdConf_s {
ral_transaction_id_t transaction_id;
ral_status_t status;
uint8_t num_link_cfg_params;
ral_link_cfg_status_t cfg_status[RAL_MAX_LINK_CFG_PARAMS];
}PhyMeasThresholdConf;
# if ENABLE_RAL
ral_transaction_id_t transaction_id;
ral_status_t status;
uint8_t num_link_cfg_params;
ral_link_cfg_status_t cfg_status[RAL_MAX_LINK_CFG_PARAMS];
#endif
} PhyMeasThresholdConf;
#endif /* PHY_MESSAGES_TYPES_H_ */
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -46,9 +46,9 @@
# define __PLATFORM_CONSTANTS_H__
#ifdef JUMBO_FRAME
#define NL_MAX_PAYLOAD 18000 /* this should cover the max mtu size*/
#define NL_MAX_PAYLOAD 18000 /* this should cover the max mtu size*/
#else
#define NL_MAX_PAYLOAD 9000 /* this should cover the max mtu size*/
#define NL_MAX_PAYLOAD 9000 /* this should cover the max mtu size*/
#endif
#ifdef USER_MODE
+135 -35
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -42,6 +42,9 @@
#include <stdint.h>
#endif
#if defined(ENABLE_ITTI)
#include "itti_types.h"
#endif
//-----------------------------------------------------------------------------
// GENERIC TYPES
//-----------------------------------------------------------------------------
@@ -65,6 +68,7 @@ typedef uint32_t frame_t;
typedef int32_t sframe_t;
typedef uint32_t sub_frame_t;
typedef uint8_t module_id_t;
typedef uint8_t eNB_index_t;
typedef uint16_t ue_id_t;
typedef int16_t smodule_id_t;
typedef uint16_t rb_id_t;
@@ -83,15 +87,15 @@ typedef boolean_t srb_flag_t;
#define SRB_FLAG_YES TRUE
typedef enum link_direction_e {
UNKNOWN_DIR = 0,
DIR_UPLINK = 1,
DIR_DOWNLINK = 2
UNKNOWN_DIR = 0,
DIR_UPLINK = 1,
DIR_DOWNLINK = 2
} link_direction_t;
typedef enum rb_type_e {
UNKNOWN_RADIO_BEARER = 0,
SIGNALLING_RADIO_BEARER = 1,
RADIO_ACCESS_BEARER = 2
UNKNOWN_RADIO_BEARER = 0,
SIGNALLING_RADIO_BEARER = 1,
RADIO_ACCESS_BEARER = 2
} rb_type_t;
//-----------------------------------------------------------------------------
@@ -109,6 +113,7 @@ typedef sdu_size_t tbs_size_t;
typedef sdu_size_t tb_size_t;
typedef unsigned int logical_chan_id_t;
typedef unsigned int num_tb_t;
typedef uint8_t mac_enb_index_t;
//-----------------------------------------------------------------------------
// RLC TYPES
@@ -121,6 +126,8 @@ typedef uint16_t rlc_usn_t;
typedef int32_t rlc_buffer_occupancy_t;
typedef signed int rlc_op_status_t;
#define SDU_CONFIRM_NO FALSE
#define SDU_CONFIRM_YES TRUE
//-----------------------------------------------------------------------------
// PDCP TYPES
//-----------------------------------------------------------------------------
@@ -129,24 +136,24 @@ typedef uint32_t pdcp_hfn_t;
typedef int16_t pdcp_hfn_offset_t;
typedef enum pdcp_transmission_mode_e {
PDCP_TRANSMISSION_MODE_UNKNOWN = 0,
PDCP_TRANSMISSION_MODE_CONTROL = 1,
PDCP_TRANSMISSION_MODE_DATA = 2,
PDCP_TRANSMISSION_MODE_TRANSPARENT = 3
PDCP_TRANSMISSION_MODE_UNKNOWN = 0,
PDCP_TRANSMISSION_MODE_CONTROL = 1,
PDCP_TRANSMISSION_MODE_DATA = 2,
PDCP_TRANSMISSION_MODE_TRANSPARENT = 3
} pdcp_transmission_mode_t;
//-----------------------------------------------------------------------------
// IP DRIVER / PDCP TYPES
//-----------------------------------------------------------------------------
typedef uint16_t tcp_udp_port_t;
typedef enum ip_traffic_type_e {
TRAFFIC_IPVX_TYPE_UNKNOWN = 0,
TRAFFIC_IPV6_TYPE_UNICAST = 1,
TRAFFIC_IPV6_TYPE_MULTICAST = 2,
TRAFFIC_IPV6_TYPE_UNKNOWN = 3,
TRAFFIC_IPV4_TYPE_UNICAST = 5,
TRAFFIC_IPV4_TYPE_MULTICAST = 6,
TRAFFIC_IPV4_TYPE_BROADCAST = 7,
TRAFFIC_IPV4_TYPE_UNKNOWN = 8
TRAFFIC_IPVX_TYPE_UNKNOWN = 0,
TRAFFIC_IPV6_TYPE_UNICAST = 1,
TRAFFIC_IPV6_TYPE_MULTICAST = 2,
TRAFFIC_IPV6_TYPE_UNKNOWN = 3,
TRAFFIC_IPV4_TYPE_UNICAST = 5,
TRAFFIC_IPV4_TYPE_MULTICAST = 6,
TRAFFIC_IPV4_TYPE_BROADCAST = 7,
TRAFFIC_IPV4_TYPE_UNKNOWN = 8
} ip_traffic_type_t;
//-----------------------------------------------------------------------------
@@ -155,14 +162,28 @@ typedef enum ip_traffic_type_e {
typedef uint32_t mbms_session_id_t;
typedef uint16_t mbms_service_id_t;
typedef uint16_t rnti_t;
typedef uint8_t rrc_enb_index_t;
#if ! defined(NOT_A_RNTI)
#define NOT_A_RNTI (rnti_t)0
#endif
#if ! defined(M_RNTI)
#define M_RNTI (rnti_t)0xFFFD
#endif
#if ! defined(P_RNTI)
#define P_RNTI (rnti_t)0xFFFE
#endif
#if ! defined(SI_RNTI)
#define SI_RNTI (rnti_t)0xFFFF
#endif
typedef enum config_action_e {
CONFIG_ACTION_NULL = 0,
CONFIG_ACTION_ADD = 1,
CONFIG_ACTION_REMOVE = 2,
CONFIG_ACTION_MODIFY = 3,
CONFIG_ACTION_SET_SECURITY_MODE = 4,
CONFIG_ACTION_MBMS_ADD = 10,
CONFIG_ACTION_MBMS_MODIFY = 11
CONFIG_ACTION_NULL = 0,
CONFIG_ACTION_ADD = 1,
CONFIG_ACTION_REMOVE = 2,
CONFIG_ACTION_MODIFY = 3,
CONFIG_ACTION_SET_SECURITY_MODE = 4,
CONFIG_ACTION_MBMS_ADD = 10,
CONFIG_ACTION_MBMS_MODIFY = 11
} config_action_t;
//-----------------------------------------------------------------------------
@@ -176,16 +197,95 @@ typedef uint8_t ebi_t; // eps bearer id
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// may be ITTI not enabled, but type instance is useful also for OTG,
#if !defined(instance_t)
typedef uint16_t instance_t;
#endif
typedef struct protocol_ctxt_s {
module_id_t enb_module_id; /*!< \brief Virtualized enb module identifier, Not used if eNB_flagP = 0. */
module_id_t ue_module_id; /*!< \brief Virtualized ue module identifier */
frame_t frame; /*!< \brief LTE Frame number.*/
eNB_flag_t enb_flag; /*!< \brief Flag to indicate eNB (1) or UE (0) */
module_id_t module_id; /*!< \brief Virtualized module identifier */
eNB_flag_t enb_flag; /*!< \brief Flag to indicate eNB (1) or UE (0) */
instance_t instance; /*!< \brief ITTI or OTG module identifier */
rnti_t rnti;
frame_t frame; /*!< \brief LTE frame number.*/
sub_frame_t subframe; /*!< \brief LTE sub frame number.*/
eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */
} protocol_ctxt_t;
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u/%02u]"
// warning time hardcoded
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe)
#define UE_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD + NB_eNB_INST
#define ENB_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD
#define UE_INSTANCE_TO_MODULE_ID( iNSTANCE ) iNSTANCE - NB_eNB_INST
#define ENB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
#define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \
if(eNB_fLAG == ENB_FLAG_YES) \
iNSTANCE = ENB_MODULE_ID_TO_INSTANCE(mODULE_iD); \
else \
iNSTANCE = UE_MODULE_ID_TO_INSTANCE(mODULE_iD)
#define INSTANCE_TO_MODULE_ID(iNSTANCE, mODULE_iD, eNB_fLAG) \
if(eNB_fLAG == ENB_FLAG_YES) \
mODULE_iD = ENB_INSTANCE_TO_MODULE_ID(iNSTANCE); \
else \
mODULE_iD = UE_INSTANCE_TO_MODULE_ID(iNSTANCE)
#define PROTOCOL_CTXT_COMPUTE_MODULE_ID(CtXt_h) \
INSTANCE_TO_MODULE_ID( (CtXt_h)->instance , (CtXt_h)->module_id , (CtXt_h)->enb_flag )
#define PROTOCOL_CTXT_COMPUTE_INSTANCE(CtXt_h) \
MODULE_ID_TO_INSTANCE( (CtXt_h)->module_id , (CtXt_h)->instance , (CtXt_h)->enb_flag )
#define PROTOCOL_CTXT_SET_BY_MODULE_ID(Ctxt_Pp, mODULE_iD, eNB_fLAG, rNTI, fRAME, sUBfRAME, eNB_iNDEX) \
(Ctxt_Pp)->module_id = mODULE_iD; \
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
(Ctxt_Pp)->rnti = rNTI; \
(Ctxt_Pp)->frame = fRAME; \
(Ctxt_Pp)->subframe = sUBfRAME; \
(Ctxt_Pp)->eNB_index = eNB_iNDEX; \
PROTOCOL_CTXT_COMPUTE_INSTANCE(Ctxt_Pp)
#define PROTOCOL_CTXT_SET_BY_INSTANCE(Ctxt_Pp, iNSTANCE, eNB_fLAG, rNTI, fRAME, sUBfRAME) \
(Ctxt_Pp)->instance = iNSTANCE; \
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
(Ctxt_Pp)->rnti = rNTI; \
(Ctxt_Pp)->frame = fRAME; \
(Ctxt_Pp)->subframe = sUBfRAME; \
PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp)
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"PRIx16"]"
#define PROTOCOL_CTXT_ARGS(CTXT_Pp) \
CTXT_Pp->frame, \
(CTXT_Pp->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \
CTXT_Pp->enb_module_id, \
CTXT_Pp->ue_module_id
(CTXT_Pp)->frame, \
((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \
(CTXT_Pp)->module_id, \
(CTXT_Pp)->rnti
#ifdef OAI_EMU
#define CHECK_CTXT_ARGS(CTXT_Pp) \
if ((CTXT_Pp)->enb_flag) {\
AssertFatal (((CTXT_Pp)->module_id >= oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),\
"eNB module id is too low (%u/%d/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_enb_local,\
oai_emulation.info.nb_enb_local);\
AssertFatal (((CTXT_Pp)->module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.nb_enb_local > 0),\
"eNB module id is too high (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);\
} else {\
AssertFatal ((CTXT_Pp)->module_id < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),\
"UE module id is too high (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);\
AssertFatal ((CTXT_Pp)->module_id >= oai_emulation.info.first_ue_local,\
"UE module id is too low (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_ue_local);\
}
#else
#define CHECK_CTXT_ARGS(CTXT_Pp)
#endif
#endif
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+159 -153
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -35,32 +35,32 @@
/* 802.21 mappings with the RRC protocol :
(Research Report RR-12-265 Mapping of IEEE 802.21 MIH primitives to EPS/LTE protocols March 13 th, 2012, Michelle WETTERWALD, Prof. Christian BONNET )
LINK EVENTS:
Link_Detected System Information
Link_Detected System Information
Link_Up RRC Connection establishment
RRC Connection re-establishment
RRC Connection reconfiguration
Link_Up RRC Connection establishment
RRC Connection re-establishment
RRC Connection reconfiguration
Link_Down RRC Connection reconfiguration
RRC Connection Release
Link_Down RRC Connection reconfiguration
RRC Connection Release
Link_Parameters_Report Measurement report
Link_Going_Down N/A
Link_Handover_Imminent N/A
Link_Handover_Complete RRC Connection reconfiguration
Link_PDU_Transmit_Status N/A
Link_Parameters_Report Measurement report
Link_Going_Down N/A
Link_Handover_Imminent N/A
Link_Handover_Complete RRC Connection reconfiguration
Link_PDU_Transmit_Status N/A
LINK COMMANDS:
Link_Capability_Discover N/A
Link_Event_Subscribe Measurement configuration
Link_Event_Unsubscribe Measurement configuration
Link_Get_Parameters Measurement configuration
Link_Configure_Thresholds Measurement configuration
Link_Action / Disconnect RRC Connection Release
Link_Action / Low Power N/A
Link_Action / Power Down RRC Connection Release
Link_Action / Power Up RRC Connection establishment
Link_Capability_Discover N/A
Link_Event_Subscribe Measurement configuration
Link_Event_Unsubscribe Measurement configuration
Link_Get_Parameters Measurement configuration
Link_Configure_Thresholds Measurement configuration
Link_Action / Disconnect RRC Connection Release
Link_Action / Low Power N/A
Link_Action / Power Down RRC Connection Release
Link_Action / Power Up RRC Connection establishment
*/
#define RRC_RAL_SYSTEM_CONFIGURATION_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_ral_system_configuration_ind
@@ -112,16 +112,22 @@ typedef MIH_C_LINK_ACTION_T ral_link_action_t;
#define RAL_LINK_STATUS_REQ_LIST_LENGTH MIH_C_LINK_STATUS_REQ_LIST_LENGTH
#define RAL_LINK_CFG_PARAM_LIST_LENGTH MIH_C_LINK_CFG_PARAM_LIST_LENGTH
typedef struct ral_network_id_s { u_int16_t length; u_int8_t val[253];} ral_network_id_t;
typedef struct ral_network_id_s {
u_int16_t length;
u_int8_t val[253];
} ral_network_id_t;
typedef struct ral_link_addr_s { u_int16_t length; u_int8_t val[RAL_LINK_ADDR_LIST_LENGTH];} ral_link_addr_t;
typedef struct ral_link_addr_s {
u_int16_t length;
u_int8_t val[RAL_LINK_ADDR_LIST_LENGTH];
} ral_link_addr_t;
typedef struct ral_sig_strength_s {
ral_choice_t choice;
union {
uint8_t dbm;
uint8_t percentage;
} _union;
ral_choice_t choice;
union {
uint8_t dbm;
uint8_t percentage;
} _union;
} ral_sig_strength_t;
#define RAL_SIG_STRENGTH_CHOICE_DBM (ral_choice_t)0
#define RAL_SIG_STRENGTH_CHOICE_PERCENTAGE (ral_choice_t)1
@@ -129,84 +135,84 @@ typedef struct ral_sig_strength_s {
// FOR ENB ONLY
typedef struct rrc_ral_system_configuration_ind_s {
plmn_t plmn_id;
unsigned int cell_id:28;
}rrc_ral_system_configuration_ind_t;
plmn_t plmn_id;
unsigned int cell_id:28;
} rrc_ral_system_configuration_ind_t;
// FOR UE ONLY
typedef struct rrc_ral_system_information_ind_s {
plmn_t plmn_id;
unsigned int cell_id:28;
uint8_t dbm; // sig strength
uint16_t sinr;
uint32_t link_data_rate; //the maximum data rate in kb/s
plmn_t plmn_id;
unsigned int cell_id:28;
uint8_t dbm; // sig strength
uint16_t sinr;
uint32_t link_data_rate; //the maximum data rate in kb/s
}rrc_ral_system_information_ind_t;
} rrc_ral_system_information_ind_t;
typedef struct ral_link_scan_resp_s {
ral_link_addr_t link_addr;
ral_network_id_t network_id;
ral_sig_strength_t sig_strength;
ral_link_addr_t link_addr;
ral_network_id_t network_id;
ral_sig_strength_t sig_strength;
} ral_link_scan_resp_t;
typedef struct rrc_ral_scan_req_s {
ral_transaction_id_t transaction_id;
ral_transaction_id_t transaction_id;
}rrc_ral_scan_req_t;
} rrc_ral_scan_req_t;
typedef struct rrc_ral_scan_conf_s {
ral_transaction_id_t transaction_id;
ral_transaction_id_t transaction_id;
#define RAL_MAX_LINK_SCAN_RESP 16
uint8_t num_scan_resp;
ral_link_scan_resp_t link_scan_resp[RAL_MAX_LINK_SCAN_RESP];
}rrc_ral_scan_conf_t;
uint8_t num_scan_resp;
ral_link_scan_resp_t link_scan_resp[RAL_MAX_LINK_SCAN_RESP];
} rrc_ral_scan_conf_t;
typedef struct rrc_ral_connection_establishment_req_s{
ral_transaction_id_t transaction_id;
typedef struct rrc_ral_connection_establishment_req_s {
ral_transaction_id_t transaction_id;
}rrc_ral_connection_establishment_req_t;
} rrc_ral_connection_establishment_req_t;
typedef struct rrc_ral_connection_establishment_conf_s{
ral_transaction_id_t transaction_id;
typedef struct rrc_ral_connection_establishment_conf_s {
ral_transaction_id_t transaction_id;
}rrc_ral_connection_establishment_conf_t;
} rrc_ral_connection_establishment_conf_t;
typedef struct rrc_ral_connection_establishment_ind_s {
uint16_t ue_id; // may be c-rnti
}rrc_ral_connection_establishment_ind_t;
uint16_t ue_id; // may be c-rnti
} rrc_ral_connection_establishment_ind_t;
typedef struct rrc_ral_connection_reestablishment_ind_s {
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
}rrc_ral_connection_reestablishment_ind_t;
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
} rrc_ral_connection_reestablishment_ind_t;
typedef struct rrc_ral_connection_reconfiguration_req_s {
ral_transaction_id_t transaction_id;
uint16_t ue_id;
ral_link_action_t link_action;
// uint8_t num_drb;
// rb_id_t drb_id[maxDRB];
// uint8_t num_srb;
}rrc_ral_connection_reconfiguration_req_t;
ral_transaction_id_t transaction_id;
uint16_t ue_id;
ral_link_action_t link_action;
// uint8_t num_drb;
// rb_id_t drb_id[maxDRB];
// uint8_t num_srb;
} rrc_ral_connection_reconfiguration_req_t;
typedef struct rrc_ral_connection_reconfiguration_ind_s {
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
}rrc_ral_connection_reconfiguration_ind_t;
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
} rrc_ral_connection_reconfiguration_ind_t;
typedef struct rrc_ral_connection_reconfiguration_ho_ind_s {
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
//unsigned int cell_id:28;
}rrc_ral_connection_reconfiguration_ho_ind_t;
uint16_t ue_id;
uint8_t num_drb;
rb_id_t drb_id[maxDRB];
uint8_t num_srb;
//unsigned int cell_id:28;
} rrc_ral_connection_reconfiguration_ho_ind_t;
@@ -215,9 +221,9 @@ typedef struct rrc_ral_connection_reconfiguration_ho_ind_s {
#define RAL_BELOW_THRESHOLD MIH_C_BELOW_THRESHOLD
#define RAL_NO_THRESHOLD 0xFF
typedef struct ral_threshold_s {
uint16_t threshold_val;
uint8_t threshold_xdir;
}ral_threshold_t;
uint16_t threshold_val;
uint8_t threshold_xdir;
} ral_threshold_t;
typedef MIH_C_LINK_PARAM_GEN_T ral_link_param_gen_t;
@@ -257,27 +263,27 @@ typedef MIH_C_LINK_PARAM_LTE_T ral_link_param_lt
#define RAL_LINK_PARAM_TYPE_CHOICE_LTE MIH_C_LINK_PARAM_TYPE_CHOICE_LTE // 12
typedef struct ral_link_param_type_s {
ral_choice_t choice;
union {
ral_link_param_gen_t link_param_gen;
ral_link_param_qos_t link_param_qos;
ral_link_param_lte_t link_param_lte;
} _union;
ral_choice_t choice;
union {
ral_link_param_gen_t link_param_gen;
ral_link_param_qos_t link_param_qos;
ral_link_param_lte_t link_param_lte;
} _union;
} ral_link_param_type_t;
typedef uint16_t ral_link_param_val_t;
typedef MIH_C_NUM_COS_TYPES_T ral_num_cos_types_t ;
typedef struct ral_qos_param_val_s {
ral_choice_t choice;
union {
ral_num_cos_types_t num_qos_types;
LIST(MIH_C_MIN_PK_TX_DELAY, min_pk_tx_delay)
LIST(MIH_C_AVG_PK_TX_DELAY, avg_pk_tx_delay)
LIST(MIH_C_MAX_PK_TX_DELAY, max_pk_tx_delay)
LIST(MIH_C_PK_DELAY_JITTER, pk_delay_jitter)
LIST(MIH_C_PK_LOSS_RATE, pk_loss_rate)
} _union;
ral_choice_t choice;
union {
ral_num_cos_types_t num_qos_types;
LIST(MIH_C_MIN_PK_TX_DELAY, min_pk_tx_delay)
LIST(MIH_C_AVG_PK_TX_DELAY, avg_pk_tx_delay)
LIST(MIH_C_MAX_PK_TX_DELAY, max_pk_tx_delay)
LIST(MIH_C_PK_DELAY_JITTER, pk_delay_jitter)
LIST(MIH_C_PK_LOSS_RATE, pk_loss_rate)
} _union;
} ral_qos_param_val_t;
#define RAL_QOS_PARAM_VAL_CHOICE_NUM_QOS_TYPES MIH_C_QOS_PARAM_VAL_CHOICE_NUM_QOS_TYPES
#define RAL_QOS_PARAM_VAL_CHOICE_MIN_PK_TX_DELAY MIH_C_QOS_PARAM_VAL_CHOICE_MIN_PK_TX_DELAY
@@ -287,84 +293,84 @@ typedef struct ral_qos_param_val_s {
#define RAL_QOS_PARAM_VAL_CHOICE_PK_LOSS_RATE MIH_C_QOS_PARAM_VAL_CHOICE_PK_LOSS_RATE
typedef struct ral_link_param_s {
ral_link_param_type_t link_param_type;
ral_choice_t choice;
union {
ral_link_param_val_t link_param_val;
ral_qos_param_val_t qos_param_val;
} _union;
ral_link_param_type_t link_param_type;
ral_choice_t choice;
union {
ral_link_param_val_t link_param_val;
ral_qos_param_val_t qos_param_val;
} _union;
} ral_link_param_t;
#define RAL_LINK_PARAM_CHOICE_LINK_PARAM_VAL MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL
#define RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL MIH_C_LINK_PARAM_CHOICE_QOS_PARAM_VAL
typedef struct ral_link_cfg_param_s {
ral_link_param_type_t link_param_type;
#define RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL 0
#define RAL_LINK_CFG_PARAM_CHOICE_TIMER 1
uint8_t union_choice;
union {
uint8_t null_attr;
uint16_t timer_interval; // This timer value (ms) is used to set the interval between periodic reports.
} _union;
#define RAL_TH_ACTION_SET_NORMAL_THRESHOLD MIH_C_SET_NORMAL_THRESHOLD
#define RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD MIH_C_SET_ONE_SHOT_THRESHOLD
#define RAL_TH_ACTION_CANCEL_THRESHOLD MIH_C_CANCEL_THRESHOLD
ral_th_action_t th_action; // indicates what action to apply to the listed thresholds.
// When “Cancel threshold” is selected and no thresholds are specified, then
// all currently configured thresholds for the given LINK_PARAM_TYPE are can-
// celled.
// When “Cancel threshold” is selected and thresholds are specified only those
// configured thresholds for the given LINK_PARAM_TYPE and whose threshold
// value match what was specified are cancelled.
// With “Set one-shot threshold” the listed thresholds are first set and then
// each of the threshold is cancelled as soon as it is crossed for the first
// time.
uint8_t num_thresholds;
#define RAL_LINK_CFG_PARAM_MAX_THRESHOLDS 16
ral_threshold_t thresholds[RAL_LINK_CFG_PARAM_MAX_THRESHOLDS];
ral_link_param_type_t link_param_type;
#define RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL 0
#define RAL_LINK_CFG_PARAM_CHOICE_TIMER 1
uint8_t union_choice;
union {
uint8_t null_attr;
uint16_t timer_interval; // This timer value (ms) is used to set the interval between periodic reports.
} _union;
#define RAL_TH_ACTION_SET_NORMAL_THRESHOLD MIH_C_SET_NORMAL_THRESHOLD
#define RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD MIH_C_SET_ONE_SHOT_THRESHOLD
#define RAL_TH_ACTION_CANCEL_THRESHOLD MIH_C_CANCEL_THRESHOLD
ral_th_action_t th_action; // indicates what action to apply to the listed thresholds.
// When “Cancel threshold” is selected and no thresholds are specified, then
// all currently configured thresholds for the given LINK_PARAM_TYPE are can-
// celled.
// When “Cancel threshold” is selected and thresholds are specified only those
// configured thresholds for the given LINK_PARAM_TYPE and whose threshold
// value match what was specified are cancelled.
// With “Set one-shot threshold” the listed thresholds are first set and then
// each of the threshold is cancelled as soon as it is crossed for the first
// time.
uint8_t num_thresholds;
#define RAL_LINK_CFG_PARAM_MAX_THRESHOLDS 16
ral_threshold_t thresholds[RAL_LINK_CFG_PARAM_MAX_THRESHOLDS];
} ral_link_cfg_param_t;
typedef struct rrc_ral_configure_threshold_req_s {
ral_transaction_id_t transaction_id;
#define RAL_MAX_LINK_CFG_PARAMS 16
uint8_t num_link_cfg_params;
ral_link_cfg_param_t link_cfg_params[RAL_MAX_LINK_CFG_PARAMS];
}rrc_ral_configure_threshold_req_t;
ral_transaction_id_t transaction_id;
#define RAL_MAX_LINK_CFG_PARAMS 16
uint8_t num_link_cfg_params;
ral_link_cfg_param_t link_cfg_params[RAL_MAX_LINK_CFG_PARAMS];
} rrc_ral_configure_threshold_req_t;
typedef struct ral_link_cfg_status_s {
ral_link_param_type_t link_param_type;
ral_threshold_t threshold;
ral_config_status_t config_status;
ral_link_param_type_t link_param_type;
ral_threshold_t threshold;
ral_config_status_t config_status;
} ral_link_cfg_status_t;
typedef struct rrc_ral_configure_threshold_conf_s {
ral_transaction_id_t transaction_id;
ral_status_t status;
uint8_t num_link_cfg_params;
ral_link_cfg_status_t cfg_status[RAL_MAX_LINK_CFG_PARAMS];
}rrc_ral_configure_threshold_conf_t;
ral_transaction_id_t transaction_id;
ral_status_t status;
uint8_t num_link_cfg_params;
ral_link_cfg_status_t cfg_status[RAL_MAX_LINK_CFG_PARAMS];
} rrc_ral_configure_threshold_conf_t;
typedef struct rrc_ral_measurement_report_ind_s{
ral_threshold_t threshold;
ral_link_param_t link_param;
}rrc_ral_measurement_report_ind_t;
typedef struct rrc_ral_measurement_report_ind_s {
ral_threshold_t threshold;
ral_link_param_t link_param;
} rrc_ral_measurement_report_ind_t;
typedef struct rrc_ral_connection_release_req_s{
ral_transaction_id_t transaction_id;
uint16_t ue_id;
}rrc_ral_connection_release_req_t;
typedef struct rrc_ral_connection_release_req_s {
ral_transaction_id_t transaction_id;
uint16_t ue_id;
} rrc_ral_connection_release_req_t;
typedef struct rrc_ral_connection_release_conf_s{
ral_transaction_id_t transaction_id;
uint16_t ue_id;
}rrc_ral_connection_release_conf_t;
typedef struct rrc_ral_connection_release_conf_s {
ral_transaction_id_t transaction_id;
uint16_t ue_id;
} rrc_ral_connection_release_conf_t;
typedef struct rrc_ral_connection_release_ind_s{
uint16_t ue_id;
}rrc_ral_connection_release_ind_t;
typedef struct rrc_ral_connection_release_ind_s {
uint16_t ue_id;
} rrc_ral_connection_release_ind_t;
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+52 -52
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -85,20 +85,20 @@ typedef UL_DCCH_Message_t RrcUlDcchMessage;
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s{
Rrc_State_t state;
Rrc_Sub_State_t sub_state;
typedef struct RrcStateInd_s {
Rrc_State_t state;
Rrc_Sub_State_t sub_state;
} RrcStateInd;
// eNB: ENB_APP -> RRC messages
typedef struct RrcConfigurationReq_s {
uint32_t cell_identity;
uint32_t cell_identity;
uint16_t tac;
uint16_t tac;
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/*
paging_drx_t default_drx;
@@ -119,55 +119,55 @@ typedef struct RrcConfigurationReq_s {
int16_t Nid_cell[MAX_NUM_CCs];// for testing, change later
int16_t N_RB_DL[MAX_NUM_CCs];// for testing, change later
int nb_antennas_tx[MAX_NUM_CCs];
int nb_antennas_rx[MAX_NUM_CCs];
long prach_root[MAX_NUM_CCs];
long prach_config_index[MAX_NUM_CCs];
BOOLEAN_t prach_high_speed[MAX_NUM_CCs];
long prach_zero_correlation[MAX_NUM_CCs];
long prach_freq_offset[MAX_NUM_CCs];
long pucch_delta_shift[MAX_NUM_CCs];
long pucch_nRB_CQI[MAX_NUM_CCs];
int nb_antennas_tx[MAX_NUM_CCs];
int nb_antennas_rx[MAX_NUM_CCs];
long prach_root[MAX_NUM_CCs];
long prach_config_index[MAX_NUM_CCs];
BOOLEAN_t prach_high_speed[MAX_NUM_CCs];
long prach_zero_correlation[MAX_NUM_CCs];
long prach_freq_offset[MAX_NUM_CCs];
long pucch_delta_shift[MAX_NUM_CCs];
long pucch_nRB_CQI[MAX_NUM_CCs];
long pucch_nCS_AN[MAX_NUM_CCs];
#ifndef Rel10
long pucch_n1_AN[MAX_NUM_CCs];
#ifndef Rel10
long pucch_n1_AN[MAX_NUM_CCs];
#endif
long pdsch_referenceSignalPower[MAX_NUM_CCs];
long pdsch_p_b[MAX_NUM_CCs];
long pdsch_referenceSignalPower[MAX_NUM_CCs];
long pdsch_p_b[MAX_NUM_CCs];
long pusch_n_SB[MAX_NUM_CCs];
long pusch_hoppingMode[MAX_NUM_CCs];
long pusch_hoppingOffset[MAX_NUM_CCs];
BOOLEAN_t pusch_enable64QAM[MAX_NUM_CCs];
BOOLEAN_t pusch_groupHoppingEnabled[MAX_NUM_CCs];
long pusch_groupAssignment[MAX_NUM_CCs];
BOOLEAN_t pusch_sequenceHoppingEnabled[MAX_NUM_CCs];
long pusch_nDMRS1[MAX_NUM_CCs];
long phich_duration[MAX_NUM_CCs];
long phich_resource[MAX_NUM_CCs];
BOOLEAN_t srs_enable[MAX_NUM_CCs];
long srs_BandwidthConfig[MAX_NUM_CCs];
long srs_SubframeConfig[MAX_NUM_CCs];
BOOLEAN_t srs_ackNackST[MAX_NUM_CCs];
BOOLEAN_t srs_MaxUpPts[MAX_NUM_CCs];
long pusch_p0_Nominal[MAX_NUM_CCs];
long pusch_alpha[MAX_NUM_CCs];
long pucch_p0_Nominal[MAX_NUM_CCs];
long msg3_delta_Preamble[MAX_NUM_CCs];
BOOLEAN_t pusch_enable64QAM[MAX_NUM_CCs];
BOOLEAN_t pusch_groupHoppingEnabled[MAX_NUM_CCs];
long pusch_groupAssignment[MAX_NUM_CCs];
BOOLEAN_t pusch_sequenceHoppingEnabled[MAX_NUM_CCs];
long pusch_nDMRS1[MAX_NUM_CCs];
long phich_duration[MAX_NUM_CCs];
long phich_resource[MAX_NUM_CCs];
BOOLEAN_t srs_enable[MAX_NUM_CCs];
long srs_BandwidthConfig[MAX_NUM_CCs];
long srs_SubframeConfig[MAX_NUM_CCs];
BOOLEAN_t srs_ackNackST[MAX_NUM_CCs];
BOOLEAN_t srs_MaxUpPts[MAX_NUM_CCs];
long pusch_p0_Nominal[MAX_NUM_CCs];
long pusch_alpha[MAX_NUM_CCs];
long pucch_p0_Nominal[MAX_NUM_CCs];
long msg3_delta_Preamble[MAX_NUM_CCs];
long ul_CyclicPrefixLength[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[MAX_NUM_CCs];
long rach_numberOfRA_Preambles[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[MAX_NUM_CCs];
long rach_numberOfRA_Preambles[MAX_NUM_CCs];
BOOLEAN_t rach_preamblesGroupAConfig[MAX_NUM_CCs];
long rach_sizeOfRA_PreamblesGroupA[MAX_NUM_CCs];
long rach_messageSizeGroupA[MAX_NUM_CCs];
e_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[MAX_NUM_CCs];
long rach_powerRampingStep[MAX_NUM_CCs];
long rach_preambleInitialReceivedTargetPower[MAX_NUM_CCs];
long rach_preambleTransMax[MAX_NUM_CCs];
long rach_raResponseWindowSize[MAX_NUM_CCs];
long rach_sizeOfRA_PreamblesGroupA[MAX_NUM_CCs];
long rach_messageSizeGroupA[MAX_NUM_CCs];
e_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[MAX_NUM_CCs];
long rach_powerRampingStep[MAX_NUM_CCs];
long rach_preambleInitialReceivedTargetPower[MAX_NUM_CCs];
long rach_preambleTransMax[MAX_NUM_CCs];
long rach_raResponseWindowSize[MAX_NUM_CCs];
long rach_macContentionResolutionTimer[MAX_NUM_CCs];
long rach_maxHARQ_Msg3Tx[MAX_NUM_CCs];
long bcch_modificationPeriodCoeff[MAX_NUM_CCs];
@@ -179,7 +179,7 @@ typedef struct RrcConfigurationReq_s {
long ue_TimersAndConstants_t311[MAX_NUM_CCs];
long ue_TimersAndConstants_n310[MAX_NUM_CCs];
long ue_TimersAndConstants_n311[MAX_NUM_CCs];
} RrcConfigurationReq;
// UE: NAS -> RRC messages
+4 -4
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -60,7 +60,7 @@ typedef volatile struct {
int timer_mrw;
int missing_pdu_indicator;
uint32_t pdu_size;
// int in_sequence_delivery; // not implemented
// int in_sequence_delivery; // not implemented
uint8_t max_rst;
uint8_t max_dat;
uint16_t poll_pdu;
@@ -187,7 +187,7 @@ typedef volatile struct {
} RRM_VARS;
# else
/* NODE_RG */
/* NODE_RG */
typedef volatile struct {
MT_CONFIG mt_config[MAX_MANAGED_RG_PER_MOBILE];
@@ -195,7 +195,7 @@ typedef volatile struct {
} RRM_VARS;
# endif
/* NODE_RG */
/* NODE_RG */
//typedef MT_CONFIG MAIN_MOBILE ;
//typedef RG_CONFIG MAIN_RADIO_GATEWAY;
+2 -2
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -72,7 +72,7 @@
// COMMON TRCH
//---------------------------
# define PREFERED_RLC_BLOCK_SIZE 336
//(43 bytes)
//(43 bytes)
# define JRRM_MAX_TTI 2
+2 -2
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -69,4 +69,4 @@
# define rtf_put write
# endif
# endif
#endif
#endif
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+221 -217
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -78,78 +78,78 @@
#define SECURITY_KEY_LENGTH 32
typedef enum cell_type_e {
CELL_MACRO_ENB,
CELL_HOME_ENB
CELL_MACRO_ENB,
CELL_HOME_ENB
} cell_type_t;
typedef enum paging_drx_e {
PAGING_DRX_32 = 0x0,
PAGING_DRX_64 = 0x1,
PAGING_DRX_128 = 0x2,
PAGING_DRX_256 = 0x3
PAGING_DRX_32 = 0x0,
PAGING_DRX_64 = 0x1,
PAGING_DRX_128 = 0x2,
PAGING_DRX_256 = 0x3
} paging_drx_t;
/* Lower value codepoint
* indicates higher priority.
*/
typedef enum paging_priority_s {
PAGING_PRIO_LEVEL1 = 0,
PAGING_PRIO_LEVEL2 = 1,
PAGING_PRIO_LEVEL3 = 2,
PAGING_PRIO_LEVEL4 = 3,
PAGING_PRIO_LEVEL5 = 4,
PAGING_PRIO_LEVEL6 = 5,
PAGING_PRIO_LEVEL7 = 6,
PAGING_PRIO_LEVEL8 = 7
PAGING_PRIO_LEVEL1 = 0,
PAGING_PRIO_LEVEL2 = 1,
PAGING_PRIO_LEVEL3 = 2,
PAGING_PRIO_LEVEL4 = 3,
PAGING_PRIO_LEVEL5 = 4,
PAGING_PRIO_LEVEL6 = 5,
PAGING_PRIO_LEVEL7 = 6,
PAGING_PRIO_LEVEL8 = 7
} paging_priority_t;
typedef enum cn_domain_s {
CN_DOMAIN_PS = 1,
CN_DOMAIN_CS = 2
CN_DOMAIN_PS = 1,
CN_DOMAIN_CS = 2
} cn_domain_t;
typedef struct net_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
char ipv4_address[16];
char ipv6_address[40];
unsigned ipv4:1;
unsigned ipv6:1;
char ipv4_address[16];
char ipv6_address[40];
} net_ip_address_t;
typedef uint64_t bitrate_t;
typedef struct ambr_s {
bitrate_t br_ul;
bitrate_t br_dl;
bitrate_t br_ul;
bitrate_t br_dl;
} ambr_t;
typedef enum priority_level_s {
PRIORITY_LEVEL_SPARE = 0,
PRIORITY_LEVEL_HIGHEST = 1,
PRIORITY_LEVEL_LOWEST = 14,
PRIORITY_LEVEL_NO_PRIORITY = 15
PRIORITY_LEVEL_SPARE = 0,
PRIORITY_LEVEL_HIGHEST = 1,
PRIORITY_LEVEL_LOWEST = 14,
PRIORITY_LEVEL_NO_PRIORITY = 15
} priority_level_t;
typedef enum pre_emp_capability_e {
PRE_EMPTION_CAPABILITY_ENABLED = 0,
PRE_EMPTION_CAPABILITY_DISABLED = 1,
PRE_EMPTION_CAPABILITY_MAX,
PRE_EMPTION_CAPABILITY_ENABLED = 0,
PRE_EMPTION_CAPABILITY_DISABLED = 1,
PRE_EMPTION_CAPABILITY_MAX,
} pre_emp_capability_t;
typedef enum pre_emp_vulnerability_e {
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
PRE_EMPTION_VULNERABILITY_MAX,
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
PRE_EMPTION_VULNERABILITY_MAX,
} pre_emp_vulnerability_t;
typedef struct allocation_retention_priority_s {
priority_level_t priority_level;
pre_emp_capability_t pre_emp_capability;
pre_emp_vulnerability_t pre_emp_vulnerability;
priority_level_t priority_level;
pre_emp_capability_t pre_emp_capability;
pre_emp_vulnerability_t pre_emp_vulnerability;
} allocation_retention_priority_t;
typedef struct security_capabilities_s {
uint16_t encryption_algorithms;
uint16_t integrity_algorithms;
uint16_t encryption_algorithms;
uint16_t integrity_algorithms;
} security_capabilities_t;
/* Provides the establishment cause for the RRC connection request as provided
@@ -158,42 +158,42 @@ typedef struct security_capabilities_s {
* 'Mobile Originating'. Defined in TS 36.331.
*/
typedef enum rrc_establishment_cause_e {
RRC_CAUSE_EMERGENCY = 0x0,
RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1,
RRC_CAUSE_MT_ACCESS = 0x2,
RRC_CAUSE_MO_SIGNALLING = 0x3,
RRC_CAUSE_MO_DATA = 0x4,
RRC_CAUSE_EMERGENCY = 0x0,
RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1,
RRC_CAUSE_MT_ACCESS = 0x2,
RRC_CAUSE_MO_SIGNALLING = 0x3,
RRC_CAUSE_MO_DATA = 0x4,
#if defined(UPDATE_RELEASE_10)
RRC_CAUSE_DELAY_TOLERANT_ACCESS = 0x5,
RRC_CAUSE_DELAY_TOLERANT_ACCESS = 0x5,
#endif
RRC_CAUSE_LAST
RRC_CAUSE_LAST
} rrc_establishment_cause_t;
typedef struct s1ap_gummei_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
uint8_t mme_code;
uint16_t mme_group_id;
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
uint8_t mme_code;
uint16_t mme_group_id;
} s1ap_gummei_t;
typedef struct s_tmsi_s {
uint8_t mme_code;
uint32_t m_tmsi;
uint8_t mme_code;
uint32_t m_tmsi;
} s_tmsi_t;
typedef enum ue_paging_identity_presenceMask_e {
UE_PAGING_IDENTITY_NONE = 0,
UE_PAGING_IDENTITY_imsi = (1 << 1),
UE_PAGING_IDENTITY_s_tmsi = (1 << 2),
UE_PAGING_IDENTITY_NONE = 0,
UE_PAGING_IDENTITY_imsi = (1 << 1),
UE_PAGING_IDENTITY_s_tmsi = (1 << 2),
} ue_paging_identity_presenceMask_t;
typedef struct ue_paging_identity_s {
ue_paging_identity_presenceMask_t presenceMask;
union {
char imsi[S1AP_IMSI_LENGTH];
s_tmsi_t s_tmsi;
} choice;
ue_paging_identity_presenceMask_t presenceMask;
union {
char imsi[S1AP_IMSI_LENGTH];
s_tmsi_t s_tmsi;
} choice;
} ue_paging_identity_t;
typedef enum ue_identities_presenceMask_e {
@@ -203,26 +203,26 @@ typedef enum ue_identities_presenceMask_e {
} ue_identities_presenceMask_t;
typedef struct ue_identity_s {
ue_identities_presenceMask_t presenceMask;
s_tmsi_t s_tmsi;
s1ap_gummei_t gummei;
ue_identities_presenceMask_t presenceMask;
s_tmsi_t s_tmsi;
s1ap_gummei_t gummei;
} ue_identity_t;
typedef struct nas_pdu_s {
/* Octet string data */
uint8_t *buffer;
/* Length of the octet string */
uint32_t length;
/* Octet string data */
uint8_t *buffer;
/* Length of the octet string */
uint32_t length;
} nas_pdu_t, ue_radio_cap_t;
typedef struct transport_layer_addr_s {
/* Length of the transport layer address buffer in bits. S1AP layer received a
* bit string<1..160> containing one of the following addresses: ipv4,
* ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but
* silently forward it to S1-U.
*/
uint8_t length;
uint8_t buffer[20]; // in network byte order
/* Length of the transport layer address buffer in bits. S1AP layer received a
* bit string<1..160> containing one of the following addresses: ipv4,
* ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but
* silently forward it to S1-U.
*/
uint8_t length;
uint8_t buffer[20]; // in network byte order
} transport_layer_addr_t;
#define TRANSPORT_LAYER_ADDR_COPY(dEST,sOURCE) \
@@ -233,102 +233,106 @@ typedef struct transport_layer_addr_s {
} while (0)
typedef struct e_rab_level_qos_parameter_s {
uint8_t qci;
uint8_t qci;
allocation_retention_priority_t allocation_retention_priority;
allocation_retention_priority_t allocation_retention_priority;
} e_rab_level_qos_parameter_t;
typedef struct e_rab_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Quality of service for this e_rab */
e_rab_level_qos_parameter_t qos;
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
nas_pdu_t nas_pdu;
/* The transport layer address for the IP packets */
transport_layer_addr_t sgw_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Quality of service for this e_rab */
e_rab_level_qos_parameter_t qos;
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
nas_pdu_t nas_pdu;
/* The transport layer address for the IP packets */
transport_layer_addr_t sgw_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_t;
typedef struct e_rab_setup_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* The transport layer address for the IP packets */
transport_layer_addr_t eNB_addr;
/* The transport layer address for the IP packets */
transport_layer_addr_t eNB_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_setup_t;
typedef struct e_rab_failed_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Cause of the failure */
// cause_t cause;
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Cause of the failure */
// cause_t cause;
} e_rab_failed_t;
typedef enum s1ap_ue_ctxt_modification_present_s {
S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0),
S1AP_UE_CONTEXT_MODIFICATION_UE_AMBR = (1 << 1),
S1AP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP = (1 << 2),
S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0),
S1AP_UE_CONTEXT_MODIFICATION_UE_AMBR = (1 << 1),
S1AP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP = (1 << 2),
} s1ap_ue_ctxt_modification_present_t;
typedef enum s1ap_paging_ind_present_s {
S1AP_PAGING_IND_PAGING_DRX = (1 << 0),
S1AP_PAGING_IND_PAGING_PRIORITY = (1 << 1),
S1AP_PAGING_IND_PAGING_DRX = (1 << 0),
S1AP_PAGING_IND_PAGING_PRIORITY = (1 << 1),
} s1ap_paging_ind_present_t;
//-------------------------------------------------------------------------------------------//
// eNB application layer -> S1AP messages
typedef struct s1ap_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;
/* 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;
/* 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;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* Default Paging DRX of the eNB as defined in TS 36.304 */
paging_drx_t default_drx;
/* Default Paging DRX of the eNB as defined in TS 36.304 */
paging_drx_t default_drx;
/* The eNB IP address to bind */
net_ip_address_t enb_ip_address;
/* The eNB IP address to bind */
net_ip_address_t enb_ip_address;
/* Nb of MME to connect to */
uint8_t nb_mme;
/* List of MME to connect to */
net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
/* Nb of MME to connect to */
uint8_t nb_mme;
/* List of MME to connect to */
net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
} s1ap_register_enb_req_t;
//-------------------------------------------------------------------------------------------//
// S1AP -> eNB application layer messages
typedef struct s1ap_register_enb_cnf_s {
/* Nb of MME connected */
uint8_t nb_mme;
/* Nb of MME connected */
uint8_t nb_mme;
} s1ap_register_enb_cnf_t;
typedef struct s1ap_deregistered_enb_ind_s {
/* Nb of MME connected */
uint8_t nb_mme;
/* Nb of MME connected */
uint8_t nb_mme;
} s1ap_deregistered_enb_ind_t;
//-------------------------------------------------------------------------------------------//
@@ -340,165 +344,165 @@ typedef struct s1ap_deregistered_enb_ind_s {
* will be the unique identifier used between RRC and S1AP.
*/
typedef struct s1ap_nas_first_req_s {
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* Establishment cause as sent by UE */
rrc_establishment_cause_t establishment_cause;
/* Establishment cause as sent by UE */
rrc_establishment_cause_t establishment_cause;
/* NAS PDU */
nas_pdu_t nas_pdu;
/* NAS PDU */
nas_pdu_t nas_pdu;
/* If this flag is set S1AP layer is expecting the GUMMEI. If = 0,
* the temporary s-tmsi is used.
*/
ue_identity_t ue_identity;
/* If this flag is set S1AP layer is expecting the GUMMEI. If = 0,
* the temporary s-tmsi is used.
*/
ue_identity_t ue_identity;
} s1ap_nas_first_req_t;
typedef struct s1ap_uplink_nas_s {
/* Unique UE identifier within an eNB */
unsigned eNB_ue_s1ap_id:24;
/* Unique UE identifier within an eNB */
unsigned eNB_ue_s1ap_id:24;
/* NAS pdu */
nas_pdu_t nas_pdu;
/* NAS pdu */
nas_pdu_t nas_pdu;
} s1ap_uplink_nas_t;
typedef struct s1ap_ue_cap_info_ind_s {
unsigned eNB_ue_s1ap_id:24;
ue_radio_cap_t ue_radio_cap;
unsigned eNB_ue_s1ap_id:24;
ue_radio_cap_t ue_radio_cap;
} s1ap_ue_cap_info_ind_t;
typedef struct s1ap_initial_context_setup_resp_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab setup-ed in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab setup-ed by RRC layers */
e_rab_setup_t e_rabs[S1AP_MAX_E_RAB];
/* Number of e_rab setup-ed in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab setup-ed by RRC layers */
e_rab_setup_t e_rabs[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be setup in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be setup */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be setup in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be setup */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
} s1ap_initial_context_setup_resp_t;
typedef struct s1ap_initial_context_setup_fail_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
/* TODO add cause */
/* TODO add cause */
} s1ap_initial_context_setup_fail_t, s1ap_ue_ctxt_modification_fail_t;
typedef struct s1ap_nas_non_delivery_ind_s {
unsigned eNB_ue_s1ap_id:24;
nas_pdu_t nas_pdu;
/* TODO: add cause */
unsigned eNB_ue_s1ap_id:24;
nas_pdu_t nas_pdu;
/* TODO: add cause */
} s1ap_nas_non_delivery_ind_t;
typedef struct s1ap_ue_ctxt_modification_req_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
/* Bit-mask of possible present parameters */
s1ap_ue_ctxt_modification_present_t present;
/* Bit-mask of possible present parameters */
s1ap_ue_ctxt_modification_present_t present;
/* Following fields are optionnaly present */
/* Following fields are optionnaly present */
/* Security key */
uint8_t security_key[SECURITY_KEY_LENGTH];
/* Security key */
uint8_t security_key[SECURITY_KEY_LENGTH];
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
/* Security capabilities */
security_capabilities_t security_capabilities;
/* Security capabilities */
security_capabilities_t security_capabilities;
} s1ap_ue_ctxt_modification_req_t;
typedef struct s1ap_ue_ctxt_modification_resp_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
} s1ap_ue_ctxt_modification_resp_t;
typedef struct s1ap_ue_release_complete_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
} s1ap_ue_release_complete_t;
//-------------------------------------------------------------------------------------------//
// S1AP -> RRC messages
typedef struct s1ap_downlink_nas_s {
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* Unique UE identifier within an eNB */
unsigned eNB_ue_s1ap_id:24;
/* Unique UE identifier within an eNB */
unsigned eNB_ue_s1ap_id:24;
/* NAS pdu */
nas_pdu_t nas_pdu;
/* NAS pdu */
nas_pdu_t nas_pdu;
} s1ap_downlink_nas_t;
typedef struct s1ap_initial_context_setup_req_s {
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
/* Security algorithms */
security_capabilities_t security_capabilities;
/* Security algorithms */
security_capabilities_t security_capabilities;
/* Security key */
uint8_t security_key[SECURITY_KEY_LENGTH];
/* Security key */
uint8_t security_key[SECURITY_KEY_LENGTH];
/* Number of e_rab to be setup in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
/* Number of e_rab to be setup in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
} s1ap_initial_context_setup_req_t;
typedef struct s1ap_paging_ind_s {
/* UE identity index value.
* Specified in 3GPP TS 36.304
*/
unsigned ue_index_value:10;
/* UE identity index value.
* Specified in 3GPP TS 36.304
*/
unsigned ue_index_value:10;
/* UE paging identity */
ue_paging_identity_t ue_paging_identity;
/* UE paging identity */
ue_paging_identity_t ue_paging_identity;
/* Indicates origin of paging */
cn_domain_t cn_domain;
/* Indicates origin of paging */
cn_domain_t cn_domain;
/* Optional fields */
paging_drx_t paging_drx;
/* Optional fields */
paging_drx_t paging_drx;
paging_priority_t paging_priority;
paging_priority_t paging_priority;
} s1ap_paging_ind_t;
// S1AP --> RRC messages
typedef struct s1ap_ue_release_command_s {
unsigned eNB_ue_s1ap_id:24;
unsigned eNB_ue_s1ap_id:24;
} s1ap_ue_release_command_t;
//-------------------------------------------------------------------------------------------//
typedef enum S1ap_Cause_e {
S1AP_CAUSE_NOTHING, /* No components present */
S1AP_CAUSE_RADIO_NETWORK,
S1AP_CAUSE_TRANSPORT,
S1AP_CAUSE_NAS,
S1AP_CAUSE_PROTOCOL,
S1AP_CAUSE_MISC,
/* Extensions may appear below */
S1AP_CAUSE_NOTHING, /* No components present */
S1AP_CAUSE_RADIO_NETWORK,
S1AP_CAUSE_TRANSPORT,
S1AP_CAUSE_NAS,
S1AP_CAUSE_PROTOCOL,
S1AP_CAUSE_MISC,
/* Extensions may appear below */
} s1ap_Cause_t;
// S1AP <-- RRC messages
typedef struct s1ap_ue_release_req_s {
unsigned eNB_ue_s1ap_id:24;
s1ap_Cause_t cause;
long cause_value;
unsigned eNB_ue_s1ap_id:24;
s1ap_Cause_t cause;
long cause_value;
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
#endif /* S1AP_MESSAGES_TYPES_H_ */
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+59 -55
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -39,94 +39,98 @@
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
enum sctp_state_e {
SCTP_STATE_CLOSED,
SCTP_STATE_SHUTDOWN,
SCTP_STATE_ESTABLISHED,
SCTP_STATE_UNREACHABLE
SCTP_STATE_CLOSED,
SCTP_STATE_SHUTDOWN,
SCTP_STATE_ESTABLISHED,
SCTP_STATE_UNREACHABLE
};
typedef struct sctp_new_association_req_s {
/* Upper layer connexion identifier */
uint16_t ulp_cnx_id;
/* 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;
/* The port to connect to */
uint16_t port;
/* Payload Protocol Identifier to use */
uint32_t ppid;
/* Local address to bind to */
net_ip_address_t local_address;
/* Remote address to connect to */
net_ip_address_t remote_address;
/* 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;
} sctp_new_association_req_t;
typedef struct sctp_new_association_ind_s {
/* Assoc id of the new association */
int32_t assoc_id;
/* Assoc id of the new association */
int32_t assoc_id;
/* The port used by remote host */
uint16_t port;
/* The port used by remote host */
uint16_t port;
/* Number of streams used for this association */
uint16_t in_streams;
uint16_t out_streams;
/* Number of streams used for this association */
uint16_t in_streams;
uint16_t out_streams;
} sctp_new_association_ind_t;
typedef struct sctp_new_association_resp_s {
/* Upper layer connexion identifier */
uint16_t ulp_cnx_id;
/* Upper layer connexion identifier */
uint16_t ulp_cnx_id;
/* SCTP Association ID */
int32_t assoc_id;
/* SCTP Association ID */
int32_t assoc_id;
/* Input/output streams */
uint16_t out_streams;
uint16_t in_streams;
/* Input/output streams */
uint16_t out_streams;
uint16_t in_streams;
/* State of the association at SCTP level */
enum sctp_state_e sctp_state;
/* State of the association at SCTP level */
enum sctp_state_e sctp_state;
} sctp_new_association_resp_t;
typedef struct sctp_data_ind_s {
/* SCTP Association ID */
int32_t assoc_id;
/* SCTP Association ID */
int32_t assoc_id;
/* Buffer to send over SCTP */
uint32_t buffer_length;
uint8_t *buffer;
/* Buffer to send over SCTP */
uint32_t buffer_length;
uint8_t *buffer;
/* Streams on which data will be sent/received */
uint16_t stream;
/* Streams on which data will be sent/received */
uint16_t stream;
} sctp_data_ind_t;
typedef struct sctp_init_s {
/* Request usage of ipv4 */
unsigned ipv4:1;
/* Request usage of ipv6 */
unsigned ipv6:1;
uint8_t nb_ipv4_addr;
uint32_t ipv4_address[10];
uint8_t nb_ipv6_addr;
char *ipv6_address[10];
uint16_t port;
uint32_t ppid;
/* Request usage of ipv4 */
unsigned ipv4:1;
/* Request usage of ipv6 */
unsigned ipv6:1;
uint8_t nb_ipv4_addr;
uint32_t ipv4_address[10];
uint8_t nb_ipv6_addr;
char *ipv6_address[10];
uint16_t port;
uint32_t ppid;
} sctp_init_t;
typedef struct sctp_close_association_s {
uint32_t assoc_id;
uint32_t assoc_id;
} sctp_close_association_t;
typedef sctp_data_ind_t sctp_data_req_t;
typedef struct sctp_listener_register_upper_layer_s {
/* Port to listen to */
uint16_t port;
/* Payload protocol identifier
* Any data receveid on PPID != will be discarded
*/
uint32_t ppid;
/* Port to listen to */
uint16_t port;
/* Payload protocol identifier
* Any data receveid on PPID != will be discarded
*/
uint32_t ppid;
} sctp_listener_register_upper_layer_t;
#endif /* SCTP_MESSAGES_TYPES_H_ */
+30 -27
View File
@@ -21,59 +21,62 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
// This task is mandatory and must always be placed in first position
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MAX, 10)
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MAX, 10)
// Other possible tasks in the process
// Common tasks:
/// Layer 2 and Layer 1 task supporting all the synchronous processing
TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX_LEAST, 200)
/// Layer 2 and Layer 1 task supporting all the synchronous processing
TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX_LEAST, 200)
/// Bearers Manager task
TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200)
/// Bearers Manager task
TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200)
// eNodeB tasks and sub-tasks:
//// Layer 2 and Layer 1 sub-tasks
//// Layer 2 and Layer 1 sub-tasks
SUB_TASK_DEF(TASK_L2L1, TASK_PHY_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_MAC_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_RLC_ENB, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_ENB, 200)
/// Radio Resource Control task
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200)
/// S1ap task
/// Radio Resource Control task
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200)
/// S1ap task
/// RAL task for ENB
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200)
// UDP TASK
TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000)
// GTP_V1U task
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000)
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200)
/// X2ap task, acts as both source and target
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200)
/// Sctp task (Used by both S1AP and X2AP)
TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200)
/// eNB APP task
TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200)
// UDP TASK
TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000)
// GTP_V1U task
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000)
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200)
/// X2ap task, acts as both source and target
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200)
/// Sctp task (Used by both S1AP and X2AP)
TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200)
/// eNB APP task
TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200)
// UE tasks and sub-tasks:
//// Layer 2 and Layer 1 sub-tasks
//// Layer 2 and Layer 1 sub-tasks
SUB_TASK_DEF(TASK_L2L1, TASK_PHY_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_MAC_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_RLC_UE, 200)
SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_UE, 200)
/// Radio Resource Control task
TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200)
/// Non Access Stratum task
TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200)
/// Radio Resource Control task
TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200)
/// Non Access Stratum task
TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200)
//MESSAGE GENERATOR TASK
TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200)
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+12 -12
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -33,23 +33,23 @@
#define UDP_INIT(mSGpTR) (mSGpTR)->ittiMsg.udp_init
typedef struct {
uint32_t port;
char *address;
uint32_t port;
char *address;
} udp_init_t;
typedef struct {
uint8_t *buffer;
uint32_t buffer_length;
uint32_t buffer_offset;
uint32_t peer_address;
uint32_t peer_port;
uint8_t *buffer;
uint32_t buffer_length;
uint32_t buffer_offset;
uint32_t peer_address;
uint32_t peer_port;
} udp_data_req_t;
typedef struct {
uint8_t *buffer;
uint32_t buffer_length;
uint32_t peer_address;
uint32_t peer_port;
uint8_t *buffer;
uint32_t buffer_length;
uint32_t peer_address;
uint32_t peer_port;
} udp_data_ind_t;
#endif /* UDP_MESSAGES_TYPES_H_ */
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+36 -36
View File
@@ -29,16 +29,16 @@
/*! \file doxy_template.h
* \brief explain how this block is organized, and how it works
* \brief explain how this block is organized, and how it works
* \author Navid Nikaein
* \date 2006-2010
* \version 4.0
* \version 4.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
* \note this a note
* \bug this is a bug
* \note this a note
* \bug this is a bug
* \warning this is a warning
*/
*/
//-----------------------------------begin group-----------------------------
@@ -50,27 +50,27 @@
There is different modules:
- OAI Address
- OAI Components
- \ref _frame
- \ref _frame
The following diagram is based on graphviz (http://www.graphviz.org/), you need to install the package to view the diagram.
The following diagram is based on graphviz (http://www.graphviz.org/), you need to install the package to view the diagram.
* \dot
* digraph group_frame {
* node [shape=rect, fontname=Helvetica, fontsize=8,style=filled,fillcolor=lightgrey];
* a [ label = " address"];
* b [ label = " component"];
* c [ label = " frame",URL="\ref _frame"];
* a->b;
* a->c;
* b->d;
* label="Architecture"
*
* a [ label = " address"];
* b [ label = " component"];
* c [ label = " frame",URL="\ref _frame"];
* a->b;
* a->c;
* b->d;
* label="Architecture"
*
* }
* \enddot
* \enddot
\section _doxy Doxygen Help
You can use the provided Doxyfile as the configuration file or alternatively run "doxygen -g Doxyfile" to generat the file.
You need at least to set the some variables in the Doxyfile including "PROJECT_NAME","PROJECT_NUMBER","INPUT","IMAGE_PATH".
You can use the provided Doxyfile as the configuration file or alternatively run "doxygen -g Doxyfile" to generat the file.
You need at least to set the some variables in the Doxyfile including "PROJECT_NAME","PROJECT_NUMBER","INPUT","IMAGE_PATH".
Doxygen help and commands can be found at http://www.stack.nl/~dimitri/doxygen/commands.html#cmdprotocol
\section _arch Architecture
@@ -78,35 +78,35 @@ Doxygen help and commands can be found at http://www.stack.nl/~dimitri/doxygen/c
You need to set the IMAGE_PATH in your Doxyfile
\image html arch.png "Architecture"
\image latex arch.eps "Architecture"
\image latex arch.eps "Architecture"
\subsection _mac MAC
thisis the mac
\subsection _rlc RLC
this is the rlc
\subsection _impl Implementation
what about the implementation
what about the implementation
*@{*/
/*!\brief OAI protocol verion */
#define OAI_PROTOCOL_Version 0x00
#define OAI_PROTOCOL_Version 0x00
/*!\brief Length in bytes of the OAI address */
#define OAI_ADDR_LEN 6
/*!\brief OAI snode type */
enum NodeType {
/*!\brief mesh routers are */
meshrouter = 1,
/*!\brief relay nodes are */
relaynode = 2,
/*!\brief clusterheads are */
clusterhead = 3
/*!\brief mesh routers are */
meshrouter = 1,
/*!\brief relay nodes are */
relaynode = 2,
/*!\brief clusterheads are */
clusterhead = 3
};
/*@}*/
/*@}*/
// --------------------------end group ------------------------------
@@ -117,13 +117,13 @@ clusterhead = 3
The Frame is composed of ....
*@{*/
*@{*/
/*! \brief the frame structure is ... */
struct frame {
u_short duration; /*!< \brief Duration in us (2 bytes) */
u_char da[OAI_ADDR_LEN];/*!< \brief Destination MAC@ (OAI_ADDR_LEN bytes) */
u_char sa[OAI_ADDR_LEN];/*!< \brief Source MAC@ (OAI_ADDR_LEN bytes)*/
u_char body[0]; /*!< \brief Body of the frame */
u_short duration; /*!< \brief Duration in us (2 bytes) */
u_char da[OAI_ADDR_LEN];/*!< \brief Destination MAC@ (OAI_ADDR_LEN bytes) */
u_char sa[OAI_ADDR_LEN];/*!< \brief Source MAC@ (OAI_ADDR_LEN bytes)*/
u_char body[0]; /*!< \brief Body of the frame */
};
/*! \brief Broadcast ID is ... */
#define BROADCAST_ID 15
@@ -139,9 +139,9 @@ struct frame {
/*! \fn int init(int,int)
* \brief this function initializes and allocates memories and etc.
* \param[in] src the memory area to copy frrm
* \param[out] dst the memory area to copy to
* \return 0 on success, otherwise -1
* \note
* \param[out] dst the memory area to copy to
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int init(int src, int dst);
+283 -280
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -68,192 +68,200 @@ extern unsigned char NB_eNB_INST;
# endif
/*------------------------------------------------------------------------------*/
static void configure_phy(uint32_t enb_id, const Enb_properties_array_t *enb_properties)
static void configure_phy(module_id_t enb_id, const Enb_properties_array_t* enb_properties)
{
MessageDef *msg_p;
int CC_id;
MessageDef *msg_p;
int CC_id;
msg_p = itti_alloc_new_message (TASK_ENB_APP, PHY_CONFIGURATION_REQ);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
PHY_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id];
PHY_CONFIGURATION_REQ (msg_p).prefix_type[CC_id] = enb_properties->properties[enb_id]->prefix_type[CC_id];
PHY_CONFIGURATION_REQ (msg_p).downlink_frequency[CC_id] = enb_properties->properties[enb_id]->downlink_frequency[CC_id];
PHY_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[CC_id] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id];
PHY_CONFIGURATION_REQ (msg_p).nb_antennas_tx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id];
PHY_CONFIGURATION_REQ (msg_p).nb_antennas_rx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id];
PHY_CONFIGURATION_REQ (msg_p).tx_gain[CC_id] = enb_properties->properties[enb_id]->tx_gain[CC_id];
PHY_CONFIGURATION_REQ (msg_p).rx_gain[CC_id] = enb_properties->properties[enb_id]->rx_gain[CC_id];
}
itti_send_msg_to_task (TASK_PHY_ENB, enb_id, msg_p);
msg_p = itti_alloc_new_message (TASK_ENB_APP, PHY_CONFIGURATION_REQ);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id];
PHY_CONFIGURATION_REQ (msg_p).prefix_type[CC_id] = enb_properties->properties[enb_id]->prefix_type[CC_id];
PHY_CONFIGURATION_REQ (msg_p).downlink_frequency[CC_id] = enb_properties->properties[enb_id]->downlink_frequency[CC_id];
PHY_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[CC_id] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id];
PHY_CONFIGURATION_REQ (msg_p).nb_antennas_tx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id];
PHY_CONFIGURATION_REQ (msg_p).nb_antennas_rx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id];
PHY_CONFIGURATION_REQ (msg_p).tx_gain[CC_id] = enb_properties->properties[enb_id]->tx_gain[CC_id];
PHY_CONFIGURATION_REQ (msg_p).rx_gain[CC_id] = enb_properties->properties[enb_id]->rx_gain[CC_id];
}
itti_send_msg_to_task (TASK_PHY_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
}
/*------------------------------------------------------------------------------*/
static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_properties)
{
MessageDef *msg_p = NULL;
int CC_id;
MessageDef *msg_p = NULL;
int CC_id;
msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_properties->properties[enb_id]->eNB_id;
RRC_CONFIGURATION_REQ (msg_p).tac = enb_properties->properties[enb_id]->tac;
RRC_CONFIGURATION_REQ (msg_p).mcc = enb_properties->properties[enb_id]->mcc;
RRC_CONFIGURATION_REQ (msg_p).mnc = enb_properties->properties[enb_id]->mnc;
RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
RRC_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id];
RRC_CONFIGURATION_REQ (msg_p).tdd_config[CC_id] = enb_properties->properties[enb_id]->tdd_config[CC_id];
RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[CC_id] = enb_properties->properties[enb_id]->tdd_config_s[CC_id];
RRC_CONFIGURATION_REQ (msg_p).eutra_band[CC_id] = enb_properties->properties[enb_id]->eutra_band[CC_id];
RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_properties->properties[enb_id]->eNB_id;
RRC_CONFIGURATION_REQ (msg_p).tac = enb_properties->properties[enb_id]->tac;
RRC_CONFIGURATION_REQ (msg_p).mcc = enb_properties->properties[enb_id]->mcc;
RRC_CONFIGURATION_REQ (msg_p).mnc = enb_properties->properties[enb_id]->mnc;
RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
// RACH-Config
RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[CC_id] = enb_properties->properties[enb_id]->rach_numberOfRA_Preambles[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[CC_id] = enb_properties->properties[enb_id]->rach_preamblesGroupAConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[CC_id] = enb_properties->properties[enb_id]->rach_sizeOfRA_PreamblesGroupA[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[CC_id] = enb_properties->properties[enb_id]->rach_messageSizeGroupA[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[CC_id] = enb_properties->properties[enb_id]->rach_messagePowerOffsetGroupB[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[CC_id] = enb_properties->properties[enb_id]->rach_powerRampingStep[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[CC_id] = enb_properties->properties[enb_id]->rach_preambleInitialReceivedTargetPower[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[CC_id] = enb_properties->properties[enb_id]->rach_preambleTransMax[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[CC_id] = enb_properties->properties[enb_id]->rach_raResponseWindowSize[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[CC_id] = enb_properties->properties[enb_id]->rach_macContentionResolutionTimer[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[CC_id] = enb_properties->properties[enb_id]->rach_maxHARQ_Msg3Tx[CC_id];
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
RRC_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id];
RRC_CONFIGURATION_REQ (msg_p).tdd_config[CC_id] = enb_properties->properties[enb_id]->tdd_config[CC_id];
RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[CC_id] = enb_properties->properties[enb_id]->tdd_config_s[CC_id];
RRC_CONFIGURATION_REQ (msg_p).eutra_band[CC_id] = enb_properties->properties[enb_id]->eutra_band[CC_id];
// BCCH-Config
RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[CC_id] = enb_properties->properties[enb_id]->bcch_modificationPeriodCoeff[CC_id];
// RACH-Config
RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[CC_id] = enb_properties->properties[enb_id]->rach_numberOfRA_Preambles[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[CC_id] = enb_properties->properties[enb_id]->rach_preamblesGroupAConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[CC_id] = enb_properties->properties[enb_id]->rach_sizeOfRA_PreamblesGroupA[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[CC_id] = enb_properties->properties[enb_id]->rach_messageSizeGroupA[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[CC_id] = enb_properties->properties[enb_id]->rach_messagePowerOffsetGroupB[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[CC_id] = enb_properties->properties[enb_id]->rach_powerRampingStep[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[CC_id] = enb_properties->properties[enb_id]->rach_preambleInitialReceivedTargetPower[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[CC_id] = enb_properties->properties[enb_id]->rach_preambleTransMax[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[CC_id] = enb_properties->properties[enb_id]->rach_raResponseWindowSize[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[CC_id] = enb_properties->properties[enb_id]->rach_macContentionResolutionTimer[CC_id];
RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[CC_id] = enb_properties->properties[enb_id]->rach_maxHARQ_Msg3Tx[CC_id];
// PCCH-Config
RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[CC_id] = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pcch_nB[CC_id] = enb_properties->properties[enb_id]->pcch_nB[CC_id];
// BCCH-Config
RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[CC_id] = enb_properties->properties[enb_id]->bcch_modificationPeriodCoeff[CC_id];
// PRACH-Config
RRC_CONFIGURATION_REQ (msg_p).prach_root[CC_id] = enb_properties->properties[enb_id]->prach_root[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_config_index[CC_id] = enb_properties->properties[enb_id]->prach_config_index[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[CC_id] = enb_properties->properties[enb_id]->prach_high_speed[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[CC_id] = enb_properties->properties[enb_id]->prach_zero_correlation[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[CC_id] = enb_properties->properties[enb_id]->prach_freq_offset[CC_id];
// PCCH-Config
RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[CC_id] = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pcch_nB[CC_id] = enb_properties->properties[enb_id]->pcch_nB[CC_id];
// PDSCH-Config
RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[CC_id] = enb_properties->properties[enb_id]->pdsch_referenceSignalPower[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[CC_id] = enb_properties->properties[enb_id]->pdsch_p_b[CC_id];
// PRACH-Config
RRC_CONFIGURATION_REQ (msg_p).prach_root[CC_id] = enb_properties->properties[enb_id]->prach_root[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_config_index[CC_id] = enb_properties->properties[enb_id]->prach_config_index[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[CC_id] = enb_properties->properties[enb_id]->prach_high_speed[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[CC_id] = enb_properties->properties[enb_id]->prach_zero_correlation[CC_id];
RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[CC_id] = enb_properties->properties[enb_id]->prach_freq_offset[CC_id];
// PUSCH-Config
RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[CC_id] = enb_properties->properties[enb_id]->pusch_n_SB[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingMode[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingOffset[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[CC_id] = enb_properties->properties[enb_id]->pusch_enable64QAM[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_groupHoppingEnabled[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[CC_id] = enb_properties->properties[enb_id]->pusch_groupAssignment[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_sequenceHoppingEnabled[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[CC_id] = enb_properties->properties[enb_id]->pusch_nDMRS1[CC_id];
// PDSCH-Config
RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[CC_id] = enb_properties->properties[enb_id]->pdsch_referenceSignalPower[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[CC_id] = enb_properties->properties[enb_id]->pdsch_p_b[CC_id];
// PUCCH-Config
// PUSCH-Config
RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[CC_id] = enb_properties->properties[enb_id]->pusch_n_SB[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingMode[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingOffset[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[CC_id] = enb_properties->properties[enb_id]->pusch_enable64QAM[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_groupHoppingEnabled[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[CC_id] = enb_properties->properties[enb_id]->pusch_groupAssignment[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_sequenceHoppingEnabled[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[CC_id] = enb_properties->properties[enb_id]->pusch_nDMRS1[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[CC_id] = enb_properties->properties[enb_id]->pucch_delta_shift[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[CC_id] = enb_properties->properties[enb_id]->pucch_nRB_CQI[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[CC_id] = enb_properties->properties[enb_id]->pucch_nCS_AN[CC_id];
// PUCCH-Config
RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[CC_id] = enb_properties->properties[enb_id]->pucch_delta_shift[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[CC_id] = enb_properties->properties[enb_id]->pucch_nRB_CQI[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[CC_id] = enb_properties->properties[enb_id]->pucch_nCS_AN[CC_id];
#ifndef Rel10
RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[CC_id] = enb_properties->properties[enb_id]->pucch_n1_AN[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[CC_id] = enb_properties->properties[enb_id]->pucch_n1_AN[CC_id];
#endif
// SRS Config
RRC_CONFIGURATION_REQ (msg_p).srs_enable[CC_id] = enb_properties->properties[enb_id]->srs_enable[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[CC_id] = enb_properties->properties[enb_id]->srs_BandwidthConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[CC_id] = enb_properties->properties[enb_id]->srs_SubframeConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[CC_id] = enb_properties->properties[enb_id]->srs_ackNackST[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[CC_id] = enb_properties->properties[enb_id]->srs_MaxUpPts[CC_id];
// SRS Config
RRC_CONFIGURATION_REQ (msg_p).srs_enable[CC_id] = enb_properties->properties[enb_id]->srs_enable[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[CC_id] = enb_properties->properties[enb_id]->srs_BandwidthConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[CC_id] = enb_properties->properties[enb_id]->srs_SubframeConfig[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[CC_id] = enb_properties->properties[enb_id]->srs_ackNackST[CC_id];
RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[CC_id] = enb_properties->properties[enb_id]->srs_MaxUpPts[CC_id];
// uplinkPowerControlCommon
// uplinkPowerControlCommon
RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pusch_p0_Nominal[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pucch_p0_Nominal[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[CC_id] = enb_properties->properties[enb_id]->pusch_alpha[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1b[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2a[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2b[CC_id];
RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[CC_id] = enb_properties->properties[enb_id]->msg3_delta_Preamble[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ul_CyclicPrefixLength[CC_id] = enb_properties->properties[enb_id]->ul_CyclicPrefixLength[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pusch_p0_Nominal[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pucch_p0_Nominal[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[CC_id] = enb_properties->properties[enb_id]->pusch_alpha[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1b[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2a[CC_id];
RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2b[CC_id];
RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[CC_id] = enb_properties->properties[enb_id]->msg3_delta_Preamble[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ul_CyclicPrefixLength[CC_id] = enb_properties->properties[enb_id]->ul_CyclicPrefixLength[CC_id];
// UE Timers and Constants
// UE Timers and Constants
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t300[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t301[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t310[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n310[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t311[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n311[CC_id];
}
itti_send_msg_to_task (TASK_RRC_ENB, enb_id, msg_p);
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t300[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t301[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t310[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n310[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t311[CC_id];
RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n311[CC_id];
}
itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
}
/*------------------------------------------------------------------------------*/
# if defined(ENABLE_USE_MME)
static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
{
uint32_t enb_id;
uint32_t mme_id;
MessageDef *msg_p;
uint32_t register_enb_pending = 0;
char *str = NULL;
struct in_addr addr;
uint32_t enb_id;
uint32_t mme_id;
MessageDef *msg_p;
uint32_t register_enb_pending = 0;
char *str = NULL;
struct in_addr addr;
# if defined(OAI_EMU)
# endif
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++)
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
# if defined(OAI_EMU)
if (oai_emulation.info.cli_start_enb[enb_id] == 1)
# endif
{
# if defined(OAI_EMU)
if (oai_emulation.info.cli_start_enb[enb_id] == 1)
# endif
{
s1ap_register_enb_req_t *s1ap_register_eNB;
s1ap_register_enb_req_t *s1ap_register_eNB;
/* note: there is an implicit relationship between the data structure and the message name */
msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
/* note: there is an implicit relationship between the data structure and the message name */
msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p);
s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p);
/* Some default/random parameters */
s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id;
s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type;
s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name;
s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac;
s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc;
s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc;
s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0];
/* Some default/random parameters */
s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id;
s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type;
s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name;
s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac;
s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc;
s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc;
s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0];
s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme;
AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, S1AP_MAX_NB_MME_IP_ADDRESS);
s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme;
AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme,
S1AP_MAX_NB_MME_IP_ADDRESS);
for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++)
{
s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4;
s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6;
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address,
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address,
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address));
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address,
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address,
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address));
}
for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) {
s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4;
s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6;
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address,
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address,
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address));
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address,
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address,
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address));
}
s1ap_register_eNB->enb_ip_address.ipv6 = 0;
s1ap_register_eNB->enb_ip_address.ipv4 = 1;
addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME;
str = inet_ntoa(addr);
strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
s1ap_register_eNB->sctp_in_streams = enb_properties->properties[enb_id]->sctp_in_streams;
s1ap_register_eNB->sctp_out_streams = enb_properties->properties[enb_id]->sctp_out_streams;
itti_send_msg_to_task (TASK_S1AP, enb_id, msg_p);
register_enb_pending++;
}
s1ap_register_eNB->enb_ip_address.ipv6 = 0;
s1ap_register_eNB->enb_ip_address.ipv4 = 1;
addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME;
str = inet_ntoa(addr);
strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
register_enb_pending++;
}
}
return register_enb_pending;
return register_enb_pending;
}
# endif
#endif
@@ -261,161 +269,156 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, con
/*------------------------------------------------------------------------------*/
void *eNB_app_task(void *args_p)
{
const Enb_properties_array_t *enb_properties_p = NULL;
const Enb_properties_array_t *enb_properties_p = NULL;
#if defined(ENABLE_ITTI)
uint32_t enb_nb = 1; /* Default number of eNB is 1 */
uint32_t enb_id_start = 0;
uint32_t enb_id_end = enb_id_start + enb_nb;
uint32_t enb_nb = 1; /* Default number of eNB is 1 */
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 registered_enb;
long enb_register_retry_timer_id;
uint32_t register_enb_pending;
uint32_t registered_enb;
long enb_register_retry_timer_id;
# endif
uint32_t enb_id;
MessageDef *msg_p = NULL;
const char *msg_name = NULL;
instance_t instance;
int result;
uint32_t enb_id;
MessageDef *msg_p = NULL;
const char *msg_name = NULL;
instance_t instance;
int result;
itti_mark_task_ready (TASK_ENB_APP);
itti_mark_task_ready (TASK_ENB_APP);
# if defined(ENABLE_USE_MME)
# if defined(OAI_EMU)
enb_nb = oai_emulation.info.nb_enb_local;
enb_id_start = oai_emulation.info.first_enb_local;
enb_id_end = oai_emulation.info.first_enb_local + enb_nb;
enb_nb = oai_emulation.info.nb_enb_local;
enb_id_start = oai_emulation.info.first_enb_local;
enb_id_end = oai_emulation.info.first_enb_local + enb_nb;
AssertFatal (enb_id_end <= NUMBER_OF_eNB_MAX,
"Last eNB index is greater or equal to maximum eNB index (%d/%d)!",
enb_id_end, NUMBER_OF_eNB_MAX);
AssertFatal (enb_id_end <= NUMBER_OF_eNB_MAX,
"Last eNB index is greater or equal to maximum eNB index (%d/%d)!",
enb_id_end, NUMBER_OF_eNB_MAX);
# endif
# endif
enb_properties_p = enb_config_get();
enb_properties_p = enb_config_get();
AssertFatal (enb_nb <= enb_properties_p->number,
"Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
enb_nb, enb_properties_p->number);
AssertFatal (enb_nb <= enb_properties_p->number,
"Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
enb_nb, enb_properties_p->number);
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++)
{
configure_phy(enb_id, enb_properties_p);
configure_rrc(enb_id, enb_properties_p);
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
configure_phy(enb_id, enb_properties_p);
configure_rrc(enb_id, enb_properties_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
/* 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
do {
// Wait for a message
itti_receive_msg (TASK_ENB_APP, &msg_p);
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
break;
# if defined(ENABLE_USE_MME)
case S1AP_REGISTER_ENB_CNF:
LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
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);
# if defined(OAI_EMU)
/* Also inform all NAS UE tasks */
for (instance = NB_eNB_INST + oai_emulation.info.first_ue_local;
instance < (NB_eNB_INST + oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local); instance ++) {
msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, instance, msg_init_p);
}
# endif
} else {
uint32_t not_associated = enb_nb - registered_enb;
LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n",
not_associated, not_associated > 1 ? "are" : "is", 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);
}
}
}
break;
case S1AP_DEREGISTERED_ENB_IND:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
/* TODO handle recovering of registration */
break;
case TIMER_HAS_EXPIRED:
LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
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);
}
break;
# endif
default:
LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name);
break;
}
# 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
/* 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
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while (1);
do
{
// Wait for a message
itti_receive_msg (TASK_ENB_APP, &msg_p);
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p))
{
case TERMINATE_MESSAGE:
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
break;
# if defined(ENABLE_USE_MME)
case S1AP_REGISTER_ENB_CNF:
LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
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);
# if defined(OAI_EMU)
/* Also inform all NAS UE tasks */
for (instance = NB_eNB_INST + oai_emulation.info.first_ue_local;
instance < (NB_eNB_INST + oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local); instance ++)
{
msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, instance, msg_init_p);
}
# endif
}
else
{
uint32_t not_associated = enb_nb - registered_enb;
LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n",
not_associated, not_associated > 1 ? "are" : "is", 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);
}
}
}
break;
case S1AP_DEREGISTERED_ENB_IND:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
/* TODO handle recovering of registration */
break;
case TIMER_HAS_EXPIRED:
LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
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);
}
break;
# endif
default:
LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while (1);
#endif
return NULL;
return NULL;
}
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+2256 -1690
View File
File diff suppressed because it is too large Load Diff
+96 -80
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -52,9 +52,6 @@
#include "RRC/LITE/MESSAGES/SystemInformationBlockType2.h"
#endif
// Hard to find a defined value for max enb...
#define MAX_ENB 16
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
struct in_addr inp;\
if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\
@@ -64,43 +61,52 @@
}\
} while (0);
/** @defgroup _enb_app ENB APP
* @ingroup _oai2
* @{
*/
// Hard to find a defined value for max enb...
#define MAX_ENB 16
typedef struct mme_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
unsigned active:1;
char *ipv4_address;
char *ipv6_address;
unsigned ipv4:1;
unsigned ipv6:1;
unsigned active:1;
char *ipv4_address;
char *ipv6_address;
} mme_ip_address_t;
typedef struct Enb_properties_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;
/* 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;
/* 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;
/* 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;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* Physical parameters */
/* Physical parameters */
int16_t nb_cc;
lte_frame_type_t frame_type[1+MAX_NUM_CCs];
uint8_t tdd_config[1+MAX_NUM_CCs];
@@ -112,57 +118,57 @@ typedef struct Enb_properties_s {
int16_t Nid_cell[1+MAX_NUM_CCs];// for testing, change later
int16_t N_RB_DL[1+MAX_NUM_CCs];// for testing, change later
int nb_antennas_tx[1+MAX_NUM_CCs];
int nb_antennas_rx[1+MAX_NUM_CCs];
int tx_gain[1+MAX_NUM_CCs];
int rx_gain[1+MAX_NUM_CCs];
long prach_root[1+MAX_NUM_CCs];
long prach_config_index[1+MAX_NUM_CCs];
BOOLEAN_t prach_high_speed[1+MAX_NUM_CCs];
long prach_zero_correlation[1+MAX_NUM_CCs];
long prach_freq_offset[1+MAX_NUM_CCs];
long pucch_delta_shift[1+MAX_NUM_CCs];
long pucch_nRB_CQI[1+MAX_NUM_CCs];
int nb_antennas_tx[1+MAX_NUM_CCs];
int nb_antennas_rx[1+MAX_NUM_CCs];
int tx_gain[1+MAX_NUM_CCs];
int rx_gain[1+MAX_NUM_CCs];
long prach_root[1+MAX_NUM_CCs];
long prach_config_index[1+MAX_NUM_CCs];
BOOLEAN_t prach_high_speed[1+MAX_NUM_CCs];
long prach_zero_correlation[1+MAX_NUM_CCs];
long prach_freq_offset[1+MAX_NUM_CCs];
long pucch_delta_shift[1+MAX_NUM_CCs];
long pucch_nRB_CQI[1+MAX_NUM_CCs];
long pucch_nCS_AN[1+MAX_NUM_CCs];
#ifndef Rel10
long pucch_n1_AN[1+MAX_NUM_CCs];
#ifndef Rel10
long pucch_n1_AN[1+MAX_NUM_CCs];
#endif
long pdsch_referenceSignalPower[1+MAX_NUM_CCs];
long pdsch_p_b[1+MAX_NUM_CCs];
long pdsch_referenceSignalPower[1+MAX_NUM_CCs];
long pdsch_p_b[1+MAX_NUM_CCs];
long pusch_n_SB[1+MAX_NUM_CCs];
long pusch_hoppingMode[1+MAX_NUM_CCs];
long pusch_hoppingOffset[1+MAX_NUM_CCs];
BOOLEAN_t pusch_enable64QAM[1+MAX_NUM_CCs];
BOOLEAN_t pusch_groupHoppingEnabled[1+MAX_NUM_CCs];
long pusch_groupAssignment[1+MAX_NUM_CCs];
BOOLEAN_t pusch_sequenceHoppingEnabled[1+MAX_NUM_CCs];
long pusch_nDMRS1[1+MAX_NUM_CCs];
long phich_duration[1+MAX_NUM_CCs];
long phich_resource[1+MAX_NUM_CCs];
BOOLEAN_t srs_enable[1+MAX_NUM_CCs];
long srs_BandwidthConfig[1+MAX_NUM_CCs];
long srs_SubframeConfig[1+MAX_NUM_CCs];
BOOLEAN_t srs_ackNackST[1+MAX_NUM_CCs];
BOOLEAN_t srs_MaxUpPts[1+MAX_NUM_CCs];
long pusch_p0_Nominal[1+MAX_NUM_CCs];
long pusch_alpha[1+MAX_NUM_CCs];
long pucch_p0_Nominal[1+MAX_NUM_CCs];
long msg3_delta_Preamble[1+MAX_NUM_CCs];
BOOLEAN_t pusch_enable64QAM[1+MAX_NUM_CCs];
BOOLEAN_t pusch_groupHoppingEnabled[1+MAX_NUM_CCs];
long pusch_groupAssignment[1+MAX_NUM_CCs];
BOOLEAN_t pusch_sequenceHoppingEnabled[1+MAX_NUM_CCs];
long pusch_nDMRS1[1+MAX_NUM_CCs];
long phich_duration[1+MAX_NUM_CCs];
long phich_resource[1+MAX_NUM_CCs];
BOOLEAN_t srs_enable[1+MAX_NUM_CCs];
long srs_BandwidthConfig[1+MAX_NUM_CCs];
long srs_SubframeConfig[1+MAX_NUM_CCs];
BOOLEAN_t srs_ackNackST[1+MAX_NUM_CCs];
BOOLEAN_t srs_MaxUpPts[1+MAX_NUM_CCs];
long pusch_p0_Nominal[1+MAX_NUM_CCs];
long pusch_alpha[1+MAX_NUM_CCs];
long pucch_p0_Nominal[1+MAX_NUM_CCs];
long msg3_delta_Preamble[1+MAX_NUM_CCs];
long ul_CyclicPrefixLength[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[1+MAX_NUM_CCs];
long rach_numberOfRA_Preambles[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[1+MAX_NUM_CCs];
e_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[1+MAX_NUM_CCs];
long rach_numberOfRA_Preambles[1+MAX_NUM_CCs];
BOOLEAN_t rach_preamblesGroupAConfig[1+MAX_NUM_CCs];
long rach_sizeOfRA_PreamblesGroupA[1+MAX_NUM_CCs];
long rach_messageSizeGroupA[1+MAX_NUM_CCs];
e_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[1+MAX_NUM_CCs];
long rach_powerRampingStep[1+MAX_NUM_CCs];
long rach_preambleInitialReceivedTargetPower[1+MAX_NUM_CCs];
long rach_preambleTransMax[1+MAX_NUM_CCs];
long rach_raResponseWindowSize[1+MAX_NUM_CCs];
long rach_sizeOfRA_PreamblesGroupA[1+MAX_NUM_CCs];
long rach_messageSizeGroupA[1+MAX_NUM_CCs];
e_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[1+MAX_NUM_CCs];
long rach_powerRampingStep[1+MAX_NUM_CCs];
long rach_preambleInitialReceivedTargetPower[1+MAX_NUM_CCs];
long rach_preambleTransMax[1+MAX_NUM_CCs];
long rach_raResponseWindowSize[1+MAX_NUM_CCs];
long rach_macContentionResolutionTimer[1+MAX_NUM_CCs];
long rach_maxHARQ_Msg3Tx[1+MAX_NUM_CCs];
long bcch_modificationPeriodCoeff[1+MAX_NUM_CCs];
@@ -174,13 +180,22 @@ typedef struct Enb_properties_s {
long ue_TimersAndConstants_t311[1+MAX_NUM_CCs];
long ue_TimersAndConstants_n310[1+MAX_NUM_CCs];
long ue_TimersAndConstants_n311[1+MAX_NUM_CCs];
/* Nb of MME to connect to */
long srb1_timer_poll_retransmit;
long srb1_timer_reordering;
long srb1_timer_status_prohibit;
long srb1_poll_pdu;
long srb1_poll_byte;
long srb1_max_retx_threshold;
/* Nb of MME to connect to */
uint8_t nb_mme;
/* List of MME to connect to */
/* List of MME to connect to */
mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
int sctp_in_streams;
int sctp_out_streams;
char *enb_interface_name_for_S1U;
in_addr_t enb_ipv4_address_for_S1U;
tcp_udp_port_t enb_port_for_S1U;
@@ -195,7 +210,7 @@ typedef struct Enb_properties_s {
uint16_t otg_ue_id[NB_MODULES_MAX+1];
uint8_t otg_app_type[NB_MODULES_MAX+1];
uint8_t otg_bg_traffic[NB_MODULES_MAX+1];
// log config
// log config
int16_t glog_level;
int16_t glog_verbosity;
int16_t hw_log_level;
@@ -220,8 +235,8 @@ typedef struct Enb_properties_s {
} Enb_properties_t;
typedef struct Enb_properties_array_s {
int number;
Enb_properties_t *properties[MAX_ENB];
int number;
Enb_properties_t *properties[MAX_ENB];
} Enb_properties_array_t;
const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP);
@@ -229,3 +244,4 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP);
const Enb_properties_array_t *enb_config_get(void);
#endif /* ENB_CONFIG_H_ */
/** @} */
+399 -338
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -57,13 +57,14 @@
#endif
/* sec 5.9, 36.321: MAC Reset Procedure */
void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) {
void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index)
{
//Resetting Bj
UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0;
//Stopping all timers
//timeAlignmentTimer expires
@@ -75,7 +76,7 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) {
// cancel all pending SRs
UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
// stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
@@ -87,418 +88,478 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) {
}
int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
int
rrc_mac_config_req(
module_id_t Mod_id,
int CC_id,
eNB_flag_t eNB_flagP,
rnti_t rntiP,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig,
MeasGapConfig_t *measGapConfig,
TDD_Config_t *tdd_Config,
MobilityControlInfo_t *mobilityControlInfo,
uint8_t *SIwindowsize,
uint16_t *SIperiod,
ARFCN_ValueEUTRA_t *ul_CarrierFreq,
long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig,
MeasGapConfig_t *measGapConfig,
TDD_Config_t *tdd_Config,
MobilityControlInfo_t *mobilityControlInfo,
uint8_t *SIwindowsize,
uint16_t *SIperiod,
ARFCN_ValueEUTRA_t *ul_CarrierFreq,
long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList
#ifdef Rel10
,uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList
#endif
,uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList
#endif
#ifdef CBA
,uint8_t num_active_cba_groups,
uint16_t cba_rnti
,uint8_t num_active_cba_groups,
uint16_t cba_rnti
#endif
) {
)
{
int i,CC_id=0;
int i;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
int UE_id = -1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
if (eNB_flagP==0) {
LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_id,eNB_index);
if (tdd_Config != NULL)
UE_mac_inst[Mod_id].tdd_Config = tdd_Config;
}else {
if (physicalConfigDedicated == NULL){
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY\n",Mod_id);
} else{
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY for UE %d (%x)\n",Mod_id,UE_id,UE_RNTI(Mod_id,UE_id));
}
LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_id,eNB_index);
if (tdd_Config != NULL) {
UE_mac_inst[Mod_id].tdd_Config = tdd_Config;
}
} else {
UE_id = find_UE_id(Mod_id, rntiP);
if (physicalConfigDedicated == NULL) {
LOG_I(MAC,"[CONFIG][eNB %d/%d] Configuring MAC/PHY\n", Mod_id, CC_id);
} else {
LOG_I(MAC,"[CONFIG][eNB %d/%d] Configuring MAC/PHY for UE %d (%x)\n", Mod_id, CC_id, UE_id, UE_RNTI(Mod_id, UE_id));
}
}
if (tdd_Config && SIwindowsize && SIperiod) {
if (eNB_flagP == ENB_FLAG_YES)
mac_xface->phy_config_sib1_eNB(Mod_id,0,tdd_Config,*SIwindowsize,*SIperiod);
else
mac_xface->phy_config_sib1_ue(Mod_id,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod);
}
if (eNB_flagP == ENB_FLAG_YES) {
mac_xface->phy_config_sib1_eNB(Mod_id, CC_id, tdd_Config, *SIwindowsize, *SIperiod);
} else {
mac_xface->phy_config_sib1_ue(Mod_id,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod);
}
}
if (radioResourceConfigCommon!=NULL) {
if (eNB_flagP==1) {
LOG_I(MAC,"[CONFIG]SIB2/3 Contents (partial)\n");
LOG_I(MAC,"[CONFIG]pusch_config_common.n_SB = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
LOG_I(MAC,"[CONFIG]pusch_config_common.hoppingMode = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
LOG_I(MAC,"[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
LOG_I(MAC,"[CONFIG]pusch_config_common.enable64QAM = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
LOG_I(MAC,"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
mac_xface->phy_config_sib2_eNB(Mod_id,0,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
}
else {
UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon;
mac_xface->phy_config_sib2_ue(Mod_id,0,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
}
if (eNB_flagP==1) {
LOG_I(MAC,"[CONFIG]SIB2/3 Contents (partial)\n");
LOG_I(MAC,"[CONFIG]pusch_config_common.n_SB = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
LOG_I(MAC,"[CONFIG]pusch_config_common.hoppingMode = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
LOG_I(MAC,"[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
LOG_I(MAC,"[CONFIG]pusch_config_common.enable64QAM = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
LOG_I(MAC,"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
mac_xface->phy_config_sib2_eNB(Mod_id, CC_id, radioResourceConfigCommon, ul_CarrierFreq, ul_Bandwidth, additionalSpectrumEmission, mbsfn_SubframeConfigList);
} else {
UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon;
mac_xface->phy_config_sib2_ue(Mod_id,0,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
}
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig!= NULL) {
if (eNB_flagP==0){
LOG_I(MAC,"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",Mod_id,eNB_index);
UE_mac_inst[Mod_id].logicalChannelConfig[logicalChannelIdentity]=logicalChannelConfig;
UE_mac_inst[Mod_id].scheduling_info.Bj[logicalChannelIdentity]=0; // initilize the bucket for this lcid
if (logicalChannelConfig->ul_SpecificParameters) {
UE_mac_inst[Mod_id].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate *
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
UE_mac_inst[Mod_id].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_id,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup);
} else {
LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_id,logicalChannelIdentity);
mac_xface->macphy_exit("NULL ul_SpecificParameters");
}
if (eNB_flagP==0) {
LOG_I(MAC,"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",Mod_id,eNB_index);
UE_mac_inst[Mod_id].logicalChannelConfig[logicalChannelIdentity]=logicalChannelConfig;
UE_mac_inst[Mod_id].scheduling_info.Bj[logicalChannelIdentity]=0; // initilize the bucket for this lcid
if (logicalChannelConfig->ul_SpecificParameters) {
UE_mac_inst[Mod_id].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate *
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
UE_mac_inst[Mod_id].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_id,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup);
} else {
LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_id,logicalChannelIdentity);
mac_xface->macphy_exit("NULL ul_SpecificParameters");
}
}
}
if (mac_MainConfig != NULL){
if (eNB_flagP==0){
LOG_I(MAC,"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",Mod_id,eNB_index);
UE_mac_inst[Mod_id].macConfig=mac_MainConfig;
UE_mac_inst[Mod_id].measGapConfig=measGapConfig;
if (mac_MainConfig->ul_SCH_Config) {
if (mac_MainConfig != NULL) {
if (eNB_flagP==0) {
LOG_I(MAC,"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",Mod_id,eNB_index);
UE_mac_inst[Mod_id].macConfig=mac_MainConfig;
UE_mac_inst[Mod_id].measGapConfig=measGapConfig;
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer)
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
else
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
if (mac_MainConfig->ul_SCH_Config) {
if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx)
UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) *mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
else
UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer)
UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer;
else
UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t)MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
}
#ifdef Rel10
if (mac_MainConfig->sr_ProhibitTimer_r9)
UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->sr_ProhibitTimer_r9;
else
UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) 0;
#endif
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer);
UE_mac_inst[Mod_id].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer);
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) {
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
} else {
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
}
UE_mac_inst[Mod_id].scheduling_info.drx_config = mac_MainConfig->drx_Config;
UE_mac_inst[Mod_id].scheduling_info.phr_config = mac_MainConfig->phr_Config;
if (mac_MainConfig->phr_Config){
UE_mac_inst[Mod_id].PHR_state = mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_id].PHR_reconfigured = 1;
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer;
UE_mac_inst[Mod_id].scheduling_info.PathlossChange = mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange;
} else {
UE_mac_inst[Mod_id].PHR_reconfigured = 0;
UE_mac_inst[Mod_id].PHR_state = MAC_MainConfig__phr_Config_PR_setup;
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
UE_mac_inst[Mod_id].scheduling_info.PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
}
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_id].scheduling_info.PathlossChange);
LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_id,
(mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1,
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF,
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF,
UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db);
if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) {
UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) *mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
} else {
UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
}
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer;
} else {
UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t)MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
}
}
#ifdef Rel10
if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} else {
UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) 0;
}
#endif
UE_mac_inst[Mod_id].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer);
UE_mac_inst[Mod_id].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer);
UE_mac_inst[Mod_id].scheduling_info.drx_config = mac_MainConfig->drx_Config;
UE_mac_inst[Mod_id].scheduling_info.phr_config = mac_MainConfig->phr_Config;
if (mac_MainConfig->phr_Config) {
UE_mac_inst[Mod_id].PHR_state = mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_id].PHR_reconfigured = 1;
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer;
UE_mac_inst[Mod_id].scheduling_info.PathlossChange = mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange;
} else {
UE_mac_inst[Mod_id].PHR_reconfigured = 0;
UE_mac_inst[Mod_id].PHR_state = MAC_MainConfig__phr_Config_PR_setup;
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
UE_mac_inst[Mod_id].scheduling_info.PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
}
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_id].scheduling_info.PathlossChange);
LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_id,
(mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1,
UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF,
UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF,
UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db);
}
}
if (physicalConfigDedicated != NULL) {
if (eNB_flagP==1){
mac_xface->phy_config_dedicated_eNB(Mod_id,0,UE_RNTI(Mod_id,UE_id),physicalConfigDedicated);
}else{
mac_xface->phy_config_dedicated_ue(Mod_id,0,eNB_index,physicalConfigDedicated);
UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc
}
}
#ifdef Rel10
if (sCellToAddMod_r10 != NULL) {
if (eNB_flagP==1){
mac_xface->phy_config_dedicated_scell_eNB(Mod_id,UE_RNTI(Mod_id,UE_id),sCellToAddMod_r10,1);
if (eNB_flagP==1) {
mac_xface->phy_config_dedicated_eNB(Mod_id, CC_id, UE_RNTI(Mod_id, UE_id), physicalConfigDedicated);
} else {
mac_xface->phy_config_dedicated_ue(Mod_id,0,eNB_index,physicalConfigDedicated);
UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc
}
else {
}
#ifdef Rel10
if (sCellToAddMod_r10 != NULL) {
if (eNB_flagP==1) {
mac_xface->phy_config_dedicated_scell_eNB(Mod_id,UE_RNTI(Mod_id,UE_id),sCellToAddMod_r10,1);
} else {
#warning "phy_config_dedicated_scell_ue is empty"
mac_xface->phy_config_dedicated_scell_ue(Mod_id,eNB_index,sCellToAddMod_r10,1);
UE_mac_inst[Mod_id].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0
}
}
#endif
if (eNB_flagP == 0) {
if (measObj!= NULL) {
if (measObj[0]!= NULL){
UE_mac_inst[Mod_id].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count;
LOG_I(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_id].n_adj_cells);
for (i=0;i<UE_mac_inst[Mod_id].n_adj_cells;i++) {
UE_mac_inst[Mod_id].adj_cell_id[i] = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId;
LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_id].adj_cell_id[i]);
}
mac_xface->phy_config_meas_ue(Mod_id,0,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id);
}
/*
if (quantityConfig != NULL) {
if (quantityConfig[0] != NULL) {
UE_mac_inst[Mod_id].quantityConfig = quantityConfig[0];
LOG_I(MAC,"UE %d configured filterCoeff.",UE_mac_inst[Mod_id].crnti);
mac_xface->phy_config_meas_ue
}
if (measObj!= NULL) {
if (measObj[0]!= NULL) {
UE_mac_inst[Mod_id].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count;
LOG_I(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_id].n_adj_cells);
for (i=0; i<UE_mac_inst[Mod_id].n_adj_cells; i++) {
UE_mac_inst[Mod_id].adj_cell_id[i] = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId;
LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_id].adj_cell_id[i]);
}
mac_xface->phy_config_meas_ue(Mod_id,0,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id);
}
/*
if (quantityConfig != NULL) {
if (quantityConfig[0] != NULL) {
UE_mac_inst[Mod_id].quantityConfig = quantityConfig[0];
LOG_I(MAC,"UE %d configured filterCoeff.",UE_mac_inst[Mod_id].crnti);
mac_xface->phy_config_meas_ue
}
}
*/
}
*/
}
}
if (eNB_flagP==0) {
if(mobilityControlInfo != NULL) {
if(mobilityControlInfo != NULL) {
LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_id,eNB_index);
ue_mac_reset(Mod_id,eNB_index);
LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_id,eNB_index);
ue_mac_reset(Mod_id,eNB_index);
if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->rach_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex;
if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pdsch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
sizeof(PDSCH_ConfigCommon_t));
}
// not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pusch_ConfigCommon,
(void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pucch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if(mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
sizeof(SoundingRS_UL_ConfigCommon_t));
}
if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->uplinkPowerControlCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon,
sizeof(UplinkPowerControlCommon_t));
}
//configure antennaInfoCommon somewhere here..
if(mobilityControlInfo->radioResourceConfigCommon.p_Max) {
//to be configured
}
if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) {
UE_mac_inst[Mod_id].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->ul_CyclicPrefixLength,
(void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength,
sizeof(UL_CyclicPrefixLength_t));
}
// store the previous rnti in case of failure, and set thenew rnti
UE_mac_inst[Mod_id].crnti_before_ho = UE_mac_inst[Mod_id].crnti;
UE_mac_inst[Mod_id].crnti = ((mobilityControlInfo->newUE_Identity.buf[0])|(mobilityControlInfo->newUE_Identity.buf[1]<<8));
LOG_I(MAC,"[UE %d] Received new identity %x from %d\n", Mod_id, UE_mac_inst[Mod_id].crnti, eNB_index);
UE_mac_inst[Mod_id].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated));
if (mobilityControlInfo->rach_ConfigDedicated){
memcpy((void*)UE_mac_inst[Mod_id].rach_ConfigDedicated,
(void*)mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
}
mac_xface->phy_config_afterHO_ue(Mod_id,0,eNB_index,mobilityControlInfo,0);
if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->rach_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex;
if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pdsch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
sizeof(PDSCH_ConfigCommon_t));
}
// not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pusch_ConfigCommon,
(void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pucch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if(mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
sizeof(SoundingRS_UL_ConfigCommon_t));
}
if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->uplinkPowerControlCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon,
sizeof(UplinkPowerControlCommon_t));
}
//configure antennaInfoCommon somewhere here..
if(mobilityControlInfo->radioResourceConfigCommon.p_Max) {
//to be configured
}
if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) {
UE_mac_inst[Mod_id].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->ul_CyclicPrefixLength,
(void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength,
sizeof(UL_CyclicPrefixLength_t));
}
// store the previous rnti in case of failure, and set thenew rnti
UE_mac_inst[Mod_id].crnti_before_ho = UE_mac_inst[Mod_id].crnti;
UE_mac_inst[Mod_id].crnti = ((mobilityControlInfo->newUE_Identity.buf[0])|(mobilityControlInfo->newUE_Identity.buf[1]<<8));
LOG_I(MAC,"[UE %d] Received new identity %x from %d\n", Mod_id, UE_mac_inst[Mod_id].crnti, eNB_index);
UE_mac_inst[Mod_id].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated));
if (mobilityControlInfo->rach_ConfigDedicated) {
memcpy((void*)UE_mac_inst[Mod_id].rach_ConfigDedicated,
(void*)mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
}
mac_xface->phy_config_afterHO_ue(Mod_id,0,eNB_index,mobilityControlInfo,0);
}
}
if (mbsfn_SubframeConfigList != NULL) {
if (eNB_flagP == 1) {
LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count);
eNB_mac_inst[Mod_id].common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_id, i,
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
if (eNB_flagP == 1) {
LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count);
eNB_mac_inst[Mod_id].common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_id, i,
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
#ifdef Rel10
eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag;
eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag;
#endif
} else { // UE
LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count);
UE_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_id, i);
UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_id,
// UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
else { // UE
LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count);
UE_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_id, i);
UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_id,
// UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
}
}
}
#ifdef Rel10
if (mbsfn_AreaInfoList != NULL) {
if (eNB_flagP == 1) {
// One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time
LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count);
eNB_mac_inst[Mod_id].common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_id,i,
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_eNB(Mod_id,0,i,eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
if (eNB_flagP == 1) {
// One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time
LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count);
eNB_mac_inst[Mod_id].common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_id,i,
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_eNB(Mod_id,0,i,eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
else { // UE
LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i,
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_ue(Mod_id,0,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
} else { // UE
LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i,
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_ue(Mod_id,0,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
}
}
if (pmch_InfoList != NULL) {
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
if (eNB_flagP == 1) {
if (eNB_flagP == 1) {
LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", pmch_InfoList->list.count);
LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", pmch_InfoList->list.count);
for (i =0; i< pmch_InfoList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
for (i =0; i< pmch_InfoList->list.count; i++) {
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[CONFIG] PMCH[%d]: This PMCH stop at subframe %ldth\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->sf_AllocEnd_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->dataMCS_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->sf_AllocEnd_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i,
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->dataMCS_r9);
// MBMS session info list in each MCH
eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i]->list.count);
}
// MBMS session info list in each MCH
eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i]->list.count);
}
else { // UE
LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",Mod_id);
for (i =0; i< pmch_InfoList->list.count; i++) {
UE_mac_inst[Mod_id].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", Mod_id, i,
UE_mac_inst[Mod_id].pmch_Config[i]->mch_SchedulingPeriod_r9);
}
UE_mac_inst[Mod_id].mcch_status = 1;
} else { // UE
LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",Mod_id);
for (i =0; i< pmch_InfoList->list.count; i++) {
UE_mac_inst[Mod_id].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", Mod_id, i,
UE_mac_inst[Mod_id].pmch_Config[i]->mch_SchedulingPeriod_r9);
}
UE_mac_inst[Mod_id].mcch_status = 1;
}
}
#endif
#ifdef CBA
if (eNB_flagP == 0){
if (cba_rnti) {
UE_mac_inst[Mod_id].cba_rnti[num_active_cba_groups-1] = cba_rnti;
LOG_D(MAC,"[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n",
Mod_id,Mod_id%num_active_cba_groups, cba_rnti,eNB_index,num_active_cba_groups);
mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,eNB_index,cba_rnti,num_active_cba_groups-1, num_active_cba_groups);
}
}else {
if (cba_rnti) {
LOG_D(MAC,"[eNB %d] configure CBA RNTI for UE %d (total active cba groups %d)\n",
Mod_id, UE_id, num_active_cba_groups);
eNB_mac_inst[Mod_id].common_channels[CC_id].num_active_cba_groups=num_active_cba_groups;
for (i=0; i < num_active_cba_groups; i ++){
if (eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] != cba_rnti + i)
eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] = cba_rnti + i;
//only configure UE ids up to num_active_cba_groups
//we use them as candidates for the transmission of dci format0)
if (UE_id%num_active_cba_groups == i){
mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,UE_id,cba_rnti + i,i,num_active_cba_groups );
LOG_D(MAC,"[eNB %d] configure CBA groups %d with RNTI %x for UE %d (total active cba groups %d)\n",
Mod_id, i, eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i],UE_id, num_active_cba_groups);
}
}
if (eNB_flagP == 0) {
if (cba_rnti) {
UE_mac_inst[Mod_id].cba_rnti[num_active_cba_groups-1] = cba_rnti;
LOG_D(MAC,"[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n",
Mod_id,Mod_id%num_active_cba_groups, cba_rnti,eNB_index,num_active_cba_groups);
mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,eNB_index,cba_rnti,num_active_cba_groups-1, num_active_cba_groups);
}
} else {
if (cba_rnti) {
LOG_D(MAC,"[eNB %d] configure CBA RNTI for UE %d (total active cba groups %d)\n",
Mod_id, UE_id, num_active_cba_groups);
eNB_mac_inst[Mod_id].common_channels[CC_id].num_active_cba_groups=num_active_cba_groups;
for (i=0; i < num_active_cba_groups; i ++) {
if (eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] != cba_rnti + i) {
eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] = cba_rnti + i;
}
//only configure UE ids up to num_active_cba_groups
//we use them as candidates for the transmission of dci format0)
if (UE_id%num_active_cba_groups == i) {
mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,UE_id,cba_rnti + i,i,num_active_cba_groups );
LOG_D(MAC,"[eNB %d] configure CBA groups %d with RNTI %x for UE %d (total active cba groups %d)\n",
Mod_id, i, eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i],UE_id, num_active_cba_groups);
}
}
}
}
#endif
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
return(0);
}
#ifdef LOCALIZATION
//------------------------------------------------------------------------------
double
rrc_get_estimated_ue_distance(module_id_t Mod_id, const frame_t frameP, uint8_t UE_id, int CC_id, uint8_t loc_type){
// localization types:
// 0: power based
// 1: time based
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
int pCCid;
uint16_t rnti;
//for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]) {
pCCid = UE_PCCID(Mod_id,UE_id);
rnti = UE_list->UE_template[pCCid][UE_id].rnti;
if(rnti == 0)
return -1;
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,pCCid,rnti);
switch (loc_type) {
case 0:
return eNB_UE_stats->distance.power_based;
break;
case 1:
return eNB_UE_stats->distance.time_based;
break;
default:
return eNB_UE_stats->distance.power_based;
}
// LOG_D(LOCALIZE, "DEBUG ME, dist = %d\n", &eNB_mac_inst[Mod_id].UE_list.UE_template[CC_id][UE_id].distance.power_based);
rrc_get_estimated_ue_distance(
const protocol_ctxt_t* const ctxt_pP,
const int CC_idP,
const uint8_t loc_typeP
)
//------------------------------------------------------------------------------
{
// localization types:
// 0: power based
// 1: time based
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
UE_list_t* UE_list = &eNB_mac_inst[ctxt_pP->module_id].UE_list;
int pCCid;
int UE_id;
if(ctxt_pP->rnti == NOT_A_RNTI) {
return -1;
}
UE_id = find_UE_id(ctxt_pP->module_id,ctxt_pP->rnti);
pCCid = UE_PCCID(ctxt_pP->module_id,UE_id);
eNB_UE_stats = mac_xface->get_eNB_UE_stats(ctxt_pP->module_id,pCCid,ctxt_pP->rnti);
switch (loc_typeP) {
case 0:
return eNB_UE_stats->distance.power_based;
break;
case 1:
return eNB_UE_stats->distance.time_based;
break;
default:
return eNB_UE_stats->distance.power_based;
}
// LOG_D(LOCALIZE, "DEBUG ME, dist = %d\n", &eNB_mac_inst[ctxt_pP->module_id].UE_list.UE_template[CC_id][UE_id].distance.power_based);
}
#endif
#endif
+396 -249
View File
File diff suppressed because it is too large Load Diff
+268 -226
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -77,7 +77,8 @@
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) {//, int calibration_flag) {
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) //, int calibration_flag) {
{
unsigned int nprb[MAX_NUM_CCs];
unsigned int nCCE[MAX_NUM_CCs];
@@ -96,117 +97,129 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
DCI_PDU *DCI_pdu[MAX_NUM_CCs];
int CC_id,i,next_i;
UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
rnti_t rnti;
LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler (UE_list->head %d)\n",module_idP, frameP, subframeP,UE_list->head);
start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
nCCE[CC_id]=0;
nprb[CC_id]=0;
RBalloc[CC_id]=0;
mbsfn_status[CC_id]=0;
}
// refresh UE list based on UEs dropped by PHY in previous subframe
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
LOG_D(MAC,"UE %d: rnti %x (%p)\n",i,UE_RNTI(module_idP,i),mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i)));
if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL)
mac_remove_ue(module_idP,i,frameP);
i = UE_list->head;
while (i>=0) {
rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i);
LOG_D(MAC,"UE %d: rnti %x (%p)\n", i, rnti,
mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti));
next_i= UE_list->next[i];
if (mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti)==NULL) {
mac_remove_ue(module_idP, i, frameP, subframeP);
}
i = next_i;
}
#if defined(ENABLE_ITTI)
do {
// Checks if a message has been sent to MAC sub-task
itti_poll_msg (TASK_MAC_ENB, &msg_p);
// Checks if a message has been sent to MAC sub-task
itti_poll_msg (TASK_MAC_ENB, &msg_p);
if (msg_p != NULL) {
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
if (msg_p != NULL) {
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p)) {
case MESSAGE_TEST:
LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
break;
switch (ITTI_MSG_ID(msg_p)) {
case MESSAGE_TEST:
LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
break;
case RRC_MAC_BCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index);
case RRC_MAC_BCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index);
// TODO process BCCH data req.
break;
// TODO process BCCH data req.
break;
case RRC_MAC_CCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);
case RRC_MAC_CCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);
// TODO process CCCH data req.
break;
// TODO process CCCH data req.
break;
#ifdef Rel10
case RRC_MAC_MCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area);
// TODO process MCCH data req.
break;
case RRC_MAC_MCCH_DATA_REQ:
LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n",
msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area);
// TODO process MCCH data req.
break;
#endif
default:
LOG_E(MAC, "Received unexpected message %s\n", msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
default:
LOG_E(MAC, "Received unexpected message %s\n", msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
} while(msg_p != NULL);
#endif
// clear DCI and BCCH contents before scheduling
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
DCI_pdu[CC_id]->Num_common_dci = 0;
DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
eNB_mac_inst[module_idP].common_channels[CC_id].bcch_active = 0;
#ifdef Rel10
eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
#endif
eNB_mac_inst[module_idP].frame = frameP;
eNB_mac_inst[module_idP].subframe = subframeP;
}
//if (subframeP%5 == 0)
//#ifdef EXMIMO
ctxt.enb_module_id = module_idP;
ctxt.ue_module_id = 0;
ctxt.frame = frameP;
ctxt.enb_flag = ENB_FLAG_YES;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,module_idP);
pdcp_run(&ctxt);
//#endif
// check HO
rrc_rx_tx(module_idP,
frameP,
1,
module_idP,
rrc_rx_tx(&ctxt,
0, // eNB index, unused in eNB
CC_id);
#ifdef Rel10
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (eNB_mac_inst[module_idP].common_channels[CC_id].MBMS_flag >0) {
start_meas(&eNB_mac_inst[module_idP].schedule_mch);
mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
stop_meas(&eNB_mac_inst[module_idP].schedule_mch);
}
}
#endif
// refresh UE list based on UEs dropped by PHY in previous subframe
/*
/*
i=UE_list->head;
while (i>=0) {
next_i = UE_list->next[i];
@@ -220,54 +233,57 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
switch (subframeP) {
case 0:
// FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
// Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
// Schedule Normal DLSCH
//
schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,nCCE);//,calibration_flag);
}
else if ((mac_xface->lte_frame_parms->tdd_config == TDD) || //TDD
(mac_xface->lte_frame_parms->tdd_config == 3) ||
(mac_xface->lte_frame_parms->tdd_config == 6)) {
} else if ((mac_xface->lte_frame_parms->tdd_config == TDD) || //TDD
(mac_xface->lte_frame_parms->tdd_config == 3) ||
(mac_xface->lte_frame_parms->tdd_config == 6)) {
//schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);//,calibration_flag);
}
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
//schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
//fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 1:
// TDD, schedule UL for subframeP 7 (TDD config 0,1) / subframeP 8 (TDD Config 6)
// FDD, schedule normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 0:
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
}
else { //FDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 0:
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE);
}
break;
case 2:
// TDD, nothing
// FDD, normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
@@ -275,64 +291,73 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE);
}
break;
case 3:
// TDD Config 2, ULSCH for subframeP 7
// TDD Config 2/5 normal DLSCH
// FDD, normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) {
case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
// no break here!
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
}
else { //FDD
//schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
//fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
switch (mac_xface->lte_frame_parms->tdd_config) {
case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
// no break here!
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,nCCE);
}
break;
case 4:
// TDD Config 1, ULSCH for subframeP 8
// TDD Config 1/2/4/5 DLSCH
// FDD UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == 1) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
// schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
// no break here!
case 2:
// no break here!
case 4:
// no break here!
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
default:
break;
}
}
else {
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE);
// schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE);
//schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status);
fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status);
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
// schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
}
// no break here!
case 2:
// no break here!
case 4:
// no break here!
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
default:
break;
}
} else {
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
// schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE);
// schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE);
schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status);
fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status);
}
}
break;
case 5:
@@ -341,165 +366,182 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
// TDD normal DLSCH
// FDD normal UL/DLSCH
schedule_SI(module_idP,frameP,nprb,nCCE);
//schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE);
if ((mac_xface->lte_frame_parms->frame_type == FDD) ) {
// schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
//schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE);
if (mac_xface->lte_frame_parms->frame_type == FDD) {
schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
} else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0
(mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6
//schedule_ulsch(module_idP,cooperation_flag,subframeP,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} else {
//schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0
(mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6
//schedule_ulsch(module_idP,cooperation_flag,subframeP,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
else {
//schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
case 6:
// TDD Config 0,1,6 ULSCH for subframes 2,3
// TDD Config 3,4,5 Normal DLSCH
// FDD normal ULSCH/DLSCH
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 0:
break;
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 5:
schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
switch (mac_xface->lte_frame_parms->tdd_config) {
case 0:
break;
default:
break;
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE);
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 5:
schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
case 7:
// TDD Config 3,4,5 Normal DLSCH
// FDD Normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 3:
case 4:
schedule_RA(module_idP,frameP,subframeP,3,nprb,nCCE); // 3 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
}
else { //FDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 3:
case 4:
schedule_RA(module_idP,frameP,subframeP,3,nprb,nCCE); // 3 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
//schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
case 8:
// TDD Config 2,3,4,5 ULSCH for subframeP 2
//
// FDD Normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 2:
case 3:
case 4:
case 5:
switch (mac_xface->lte_frame_parms->tdd_config) {
case 2:
case 3:
case 4:
case 5:
// schedule_RA(module_idP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
}
else { //FDD
// schedule_RA(module_idP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
//schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
case 9:
// TDD Config 1,3,4,6 ULSCH for subframes 3,3,3,4
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE); // 7 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 2:
case 5:
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE);
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE); // 7 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 2:
case 5:
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
break;
}
} else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
}
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
DCI_pdu[CC_id]->nCCE = nCCE[CC_id];
}
LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE[0]);
stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
}
+377 -390
View File
@@ -21,13 +21,13 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
/*! \file eNB_scheduler_RAs.c
/*! \file eNB_scheduler_RA.c
* \brief primitives used for random access
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
@@ -38,8 +38,10 @@
*/
#include "assertions.h"
#include "platform_types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "msc.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
@@ -64,422 +66,407 @@
# include "intertask_interface.h"
#endif
extern inline unsigned int taus(void);
#include "SIMULATION/TOOLS/defs.h" // for taus
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned int *nprb,unsigned int *nCCE) {
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned int *nprb,unsigned int *nCCE)
{
int CC_id;
eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
int CC_id;
eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
RA_TEMPLATE *RA_template;
unsigned char i;//,harq_pid,round;
int16_t rrc_sdu_length;
unsigned char lcid,offset;
module_id_t UE_id= UE_INDEX_INVALID;
unsigned short TBsize = -1;
unsigned short msg4_padding,msg4_post_padding,msg4_header;
RA_TEMPLATE *RA_template;
unsigned char i;//,harq_pid,round;
int16_t rrc_sdu_length;
unsigned char lcid,offset;
module_id_t UE_id= UE_INDEX_INVALID;
unsigned short TBsize = -1;
unsigned short msg4_padding,msg4_post_padding,msg4_header;
start_meas(&eNB->schedule_ra);
start_meas(&eNB->schedule_ra);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
RA_template = (RA_TEMPLATE *)&eNB->common_channels[CC_id].RA_template[0];
for (i=0;i<NB_RA_PROC_MAX;i++) {
RA_template = (RA_TEMPLATE *)&eNB->common_channels[CC_id].RA_template[0];
if (RA_template[i].RA_active == TRUE) {
for (i=0; i<NB_RA_PROC_MAX; i++) {
LOG_D(MAC,"[eNB %d][RAPROC] RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,i,RA_template[i].generate_rar,RA_template[i].generate_Msg4,RA_template[i].wait_ack_Msg4, RA_template[i].rnti);
if (RA_template[i].RA_active == TRUE) {
if (RA_template[i].generate_rar == 1) {
nprb[CC_id]= nprb[CC_id] + 3;
nCCE[CC_id] = nCCE[CC_id] + 4;
RA_template[i].Msg3_subframe=Msg3_subframe;
}
else if (RA_template[i].generate_Msg4 == 1) {
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,CC_id,i,RA_template[i].generate_rar,RA_template[i].generate_Msg4,RA_template[i].wait_ack_Msg4, RA_template[i].rnti);
// check for Msg4 Message
UE_id = find_UE_id(module_idP,RA_template[i].rnti);
if (Is_rrc_registered == 1) {
if (RA_template[i].generate_rar == 1) {
nprb[CC_id]= nprb[CC_id] + 3;
nCCE[CC_id] = nCCE[CC_id] + 4;
RA_template[i].Msg3_subframe=Msg3_subframe;
} else if (RA_template[i].generate_Msg4 == 1) {
// Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP,
frameP,
CCCH,1,
&eNB->common_channels[CC_id].CCCH_pdu.payload[0],
1,
module_idP,
0); // not used in this case
if (rrc_sdu_length == -1) {
mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n");
return; // not reached
} else {
//msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length);
}
}
// check for Msg4 Message
UE_id = find_UE_id(module_idP,RA_template[i].rnti);
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n",
module_idP,frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length);
if (Is_rrc_registered == 1) {
if (rrc_sdu_length>0) {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n",
module_idP,frameP, subframeP,i,RA_template[i].rnti);
// Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
frameP,
CCCH,
1, // 1 transport block
&eNB->common_channels[CC_id].CCCH_pdu.payload[0],
ENB_FLAG_YES,
module_idP,
0); // not used in this case
//msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length);
// for (j=0;j<rrc_sdu_length;j++)
// msg("%x ",(unsigned char)eNB_mac_inst[module_idP][CC_id].CCCH_pdu.payload[j]);
// msg("\n");
// msg("[MAC][eNB] Frame %d, subframeP %d: Generated DLSCH (Msg4) DCI, format 1A, for UE %d\n",frameP, subframeP,UE_id);
// Schedule Reflection of Connection request
// Compute MCS for 3 PRB
msg4_header = 1+6+1; // CR header, CR CE, SDU header
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
}
else { // FDD DCI
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
}
RA_template[i].generate_Msg4=0;
RA_template[i].generate_Msg4_dci=1;
RA_template[i].wait_ack_Msg4=1;
RA_template[i].RA_active = FALSE;
lcid=0;
if ((TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0;
}
else {
msg4_padding = 0;
msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1;
}
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
1, //num_sdus
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
RA_template[i].cont_res_id, // contention res id
msg4_padding, // no padding
msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&eNB->common_channels[CC_id].CCCH_pdu.payload[0],
rrc_sdu_length);
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled){
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
}
#endif
nprb[CC_id]= nprb[CC_id] + 3;
nCCE[CC_id] = nCCE[CC_id] + 4;
}
//try here
}
/*
else if (eNB_mac_inst[module_idP][CC_id].RA_template[i].wait_ack_Msg4==1) {
// check HARQ status and retransmit if necessary
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP);
// Get candidate harq_pid from PHY
mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP][CC_id].RA_template[i].rnti,subframeP,&harq_pid,&round,0);
if (round>0) {
*nprb= (*nprb) + 3;
*nCCE = (*nCCE) + 4;
}
}
*/
if (rrc_sdu_length == -1) {
mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n");
return; // not reached
} else {
//msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length);
}
}
}
stop_meas(&eNB->schedule_ra);
}
}
void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,uint8_t f_id) {
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n",
module_idP, CC_id, frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length);
uint8_t i;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0];
if (rrc_sdu_length>0) {
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n",
module_idP, CC_id, frameP, subframeP,i,RA_template[i].rnti);
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Initiating RA procedure for preamble index %d\n",module_idP,frameP,preamble_index);
//msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length);
// for (j=0;j<rrc_sdu_length;j++)
// msg("%x ",(unsigned char)eNB_mac_inst[module_idP][CC_id].CCCH_pdu.payload[j]);
// msg("\n");
// msg("[MAC][eNB] Frame %d, subframeP %d: Generated DLSCH (Msg4) DCI, format 1A, for UE %d\n",frameP, subframeP,UE_id);
// Schedule Reflection of Connection request
// Compute MCS for 3 PRB
msg4_header = 1+6+1; // CR header, CR CE, SDU header
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
} else { // FDD DCI
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
}
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (RA_template[i].RA_active==FALSE) {
RA_template[i].RA_active=TRUE;
RA_template[i].generate_rar=1;
RA_template[i].generate_Msg4=0;
RA_template[i].wait_ack_Msg4=0;
RA_template[i].timing_offset=timing_offset;
// Put in random rnti (to be replaced with proper procedure!!)
RA_template[i].rnti = taus();
RA_template[i].RA_rnti = 1+subframeP+(10*f_id);
RA_template[i].preamble_index = preamble_index;
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n",
module_idP,frameP,i,RA_template[i].rnti,
RA_template[i].RA_active);
RA_template[i].generate_Msg4_dci=1;
RA_template[i].wait_ack_Msg4=1;
RA_template[i].RA_active = FALSE;
lcid=0;
return;
if ((TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0;
} else {
msg4_padding = 0;
msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1;
}
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,CC_id,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
1, //num_sdus
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
RA_template[i].cont_res_id, // contention res id
msg4_padding, // no padding
msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&eNB->common_channels[CC_id].CCCH_pdu.payload[0],
rrc_sdu_length);
if (opt_enabled==1) {
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
}
nprb[CC_id]= nprb[CC_id] + 3;
nCCE[CC_id] = nCCE[CC_id] + 4;
}
//try here
}
/*
else if (eNB_mac_inst[module_idP][CC_id].RA_template[i].wait_ack_Msg4==1) {
// check HARQ status and retransmit if necessary
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP);
// Get candidate harq_pid from PHY
mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP][CC_id].RA_template[i].rnti,subframeP,&harq_pid,&round,0);
if (round>0) {
*nprb= (*nprb) + 3;
*nCCE = (*nCCE) + 4;
}
}
*/
}
}
}
stop_meas(&eNB->schedule_ra);
}
void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rnti) {
unsigned char i;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0];
void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,
uint8_t f_id)
{
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,frameP,rnti);
uint8_t i;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0];
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (rnti == RA_template[i].rnti) {
RA_template[i].RA_active=FALSE;
RA_template[i].generate_rar=0;
RA_template[i].generate_Msg4=0;
RA_template[i].wait_ack_Msg4=0;
RA_template[i].timing_offset=0;
RA_template[i].RRC_timer=20;
RA_template[i].rnti = 0;
}
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index);
for (i=0; i<NB_RA_PROC_MAX; i++) {
if (RA_template[i].RA_active==FALSE) {
RA_template[i].RA_active=TRUE;
RA_template[i].generate_rar=1;
RA_template[i].generate_Msg4=0;
RA_template[i].wait_ack_Msg4=0;
RA_template[i].timing_offset=timing_offset;
// Put in random rnti (to be replaced with proper procedure!!)
RA_template[i].rnti = taus();
RA_template[i].RA_rnti = 1+subframeP+(10*f_id);
RA_template[i].preamble_index = preamble_index;
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n",
module_idP,CC_id,frameP,i,RA_template[i].rnti,
RA_template[i].RA_active);
return;
}
}
}
void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rnti)
{
unsigned char i;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0];
MSC_LOG_EVENT(MSC_PHY_ENB, "RA Cancelling procedure ue %"PRIx16" ", rnti);
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,CC_id,frameP,rnti);
for (i=0; i<NB_RA_PROC_MAX; i++) {
if (rnti == RA_template[i].rnti) {
RA_template[i].RA_active=FALSE;
RA_template[i].generate_rar=0;
RA_template[i].generate_Msg4=0;
RA_template[i].wait_ack_Msg4=0;
RA_template[i].timing_offset=0;
RA_template[i].RRC_timer=20;
RA_template[i].rnti = 0;
}
}
}
+89 -69
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -67,7 +67,16 @@
#define DEBUG_eNB_SCHEDULER 1
void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsigned int *nCCEP) {
//------------------------------------------------------------------------------
void
schedule_SI(
module_id_t module_idP,
frame_t frameP,
unsigned int* nprbP,
unsigned int* nCCEP
)
//------------------------------------------------------------------------------
{
@@ -79,77 +88,84 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsi
start_meas(&eNB->schedule_si);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu;
bcch_sdu_length = mac_rrc_data_req(module_idP,
frameP,
BCCH,1,
&eNB->common_channels[CC_id].BCCH_pdu.payload[0],
1,
module_idP,
0); // not used in this case
CC_id,
frameP,
BCCH,1,
&eNB->common_channels[CC_id].BCCH_pdu.payload[0],
1,
module_idP,
0); // not used in this case
if (bcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,CC_id,frameP,bcch_sdu_length);
if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3)))
LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length);
if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3))) {
mcs=0;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3))) {
mcs=1;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(2,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(2,3))) {
mcs=2;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(3,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(3,3))) {
mcs=3;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(4,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(4,3))) {
mcs=4;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(5,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(5,3))) {
mcs=5;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(6,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(6,3))) {
mcs=6;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(7,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(7,3))) {
mcs=7;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3)))
} else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3))) {
mcs=8;
}
if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 25:
((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 50:
((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 100:
((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
}
}
else {
switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 25:
((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 50:
((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 100:
((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
}
switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 25:
((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 50:
((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 100:
((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
}
} else {
switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 25:
((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 50:
((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
case 100:
((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
}
}
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled) {
if (opt_enabled == 1) {
trace_pdu(1,
&eNB->common_channels[CC_id].BCCH_pdu.payload[0],
bcch_sdu_length,
@@ -159,36 +175,40 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsi
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);
}
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, 0xffff, bcch_sdu_length);
#endif
if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n",
frameP,
bcch_sdu_length,
mcs,
mac_xface->get_TBS_DL(mcs,3));
}
else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n",
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3, TBS %d)\n",
frameP,
CC_id,
bcch_sdu_length,
mcs,
mac_xface->get_TBS_DL(mcs,3));
} else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3, TBS %d)\n",
frameP,
CC_id,
bcch_sdu_length,
mcs,
mac_xface->get_TBS_DL(mcs,3));
}
eNB->common_channels[CC_id].bcch_active=1;
nprbP[CC_id]=3;
nCCEP[CC_id]=4;
}
else {
eNB->eNB_stats[CC_id].total_num_bcch_pdu+=1;
eNB->eNB_stats[CC_id].bcch_buffer=bcch_sdu_length;
eNB->eNB_stats[CC_id].total_bcch_buffer+=bcch_sdu_length;
eNB->eNB_stats[CC_id].bcch_mcs=mcs;
} else {
eNB->common_channels[CC_id].bcch_active=0;
nprbP[CC_id]=0;
nCCEP[CC_id]=0;
//LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
}
}
// this might be misleading when bcch is inactive
stop_meas(&eNB->schedule_si);
return;
File diff suppressed because it is too large Load Diff
+489 -396
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -63,27 +63,29 @@
# include "intertask_interface.h"
#endif
#include "SIMULATION/TOOLS/defs.h" // for taus
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1
extern inline unsigned int taus(void);
#ifdef Rel10
int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area){
int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area)
{
// currently there is one-to-one mapping between sf allocation pattern and sync area
if (mbsfn_sync_area > MAX_MBSFN_AREA){
LOG_W(MAC,"[eNB %d] MBSFN synchronization area %d out of range\n ", module_idP, mbsfn_sync_area);
return -1;
}
else if (eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL)
if (mbsfn_sync_area > MAX_MBSFN_AREA) {
LOG_W(MAC,"[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", module_idP, CC_id, mbsfn_sync_area);
return -1;
} else if (eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) {
return mbsfn_sync_area;
else {
LOG_W(MAC,"[eNB %d] MBSFN Subframe Config pattern %d not found \n ", module_idP, mbsfn_sync_area);
return -1;
} else {
LOG_W(MAC,"[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ", module_idP, CC_id, mbsfn_sync_area);
return -1;
}
}
int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP) {
int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP)
{
int mcch_flag=0,mtch_flag=0, msi_flag=0;
int mbsfn_period =0;// 1<<(eNB_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
@@ -104,204 +106,262 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.Pdu_size=0;
for (i=0;
i< eNB_mac_inst[module_idP].common_channels[CC_id].num_active_mbsfn_area;
i++ ){
// assume, that there is always a mapping
if ((j=get_mbsfn_sf_alloction(module_idP,CC_id,i)) == -1)
return 0;
i< eNB_mac_inst[module_idP].common_channels[CC_id].num_active_mbsfn_area;
i++ ) {
// assume, that there is always a mapping
if ((j=get_mbsfn_sf_alloction(module_idP,CC_id,i)) == -1) {
return 0;
}
mbsfn_period = 1<<(eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
mcch_period = 32<<(eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
msi_pos=0; ii=0;
LOG_D(MAC,"[eNB %d] Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n",
module_idP,frameP, subframeP,i,eNB_mac_inst[module_idP].common_channels[CC_id].num_active_mbsfn_area,
mbsfn_period = 1<<(eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
mcch_period = 32<<(eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
msi_pos=0;
ii=0;
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n",
module_idP, CC_id, frameP, subframeP,i,eNB_mac_inst[module_idP].common_channels[CC_id].num_active_mbsfn_area,
j,eNB_mac_inst[module_idP].common_channels[CC_id].num_sf_allocation_pattern,mbsfn_period,mcch_period);
switch (eNB_mac_inst[module_idP].common_channels[CC_id].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;
}
switch (eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
case 0:
mcch_mcs = 2;
break;
// 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist)
if (frameP % mbsfn_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset){ // MBSFN frameP
if (eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame){// one-frameP format
case 1:
mcch_mcs = 7;
break;
// Find the first subframeP in this MCH to transmit MSI
if (frameP % mch_scheduling_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) {
while (ii == 0) {
ii = eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos);
msi_pos++;
}
LOG_D(MAC,"[eNB %d] Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", module_idP,frameP, subframeP,i,j,eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], msi_pos);
case 2:
mcch_mcs = 13;
break;
case 3:
mcch_mcs = 19;
break;
}
// 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist)
if (frameP % mbsfn_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
if (eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
// Find the first subframeP in this MCH to transmit MSI
if (frameP % mch_scheduling_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) {
while (ii == 0) {
ii = eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos);
msi_pos++;
}
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n",
module_idP, CC_id, frameP, subframeP,i,j,
eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], msi_pos);
}
// Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
switch (subframeP) {
case 1:
if (mac_xface->lte_frame_parms->frame_type == FDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
if (msi_pos == 1) {
msi_flag = 1;
}
// Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
switch (subframeP) {
case 1:
if (mac_xface->lte_frame_parms->frame_type == FDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 2:
if (mac_xface->lte_frame_parms->frame_type == FDD){
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
if (msi_pos == 2)
msi_flag = 1;
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 3:
if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
if (msi_pos == 1)
msi_flag = 1;
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) )
mcch_flag = 1;
mtch_flag = 1;
}
}
else {// FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 4:
if (mac_xface->lte_frame_parms->frame_type == TDD){
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 6:
if (mac_xface->lte_frame_parms->frame_type == FDD){
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 7:
if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) )
mcch_flag = 1;
mtch_flag = 1;
}
}
else {// FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 8:
if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
if (msi_pos == 4)
msi_flag = 1;
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) )
mcch_flag = 1;
mtch_flag = 1;
}
}
else{ // FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
case 9:
if (mac_xface->lte_frame_parms->frame_type == TDD){
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) )
mcch_flag = 1;
mtch_flag = 1;
}
}
break;
}// end switch
// sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)){
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
module_idP, frameP, subframeP,i,j,msi_flag,mcch_flag,mtch_flag);
break;
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
else {// four-frameP format
break;
case 2:
if (mac_xface->lte_frame_parms->frame_type == FDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
if (msi_pos == 2) {
msi_flag = 1;
}
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 3:
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
if (msi_pos == 1) {
msi_flag = 1;
}
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
} else { // FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 4:
if (mac_xface->lte_frame_parms->frame_type == TDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 6:
if (mac_xface->lte_frame_parms->frame_type == FDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 7:
if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
} else { // FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 8:
if (mac_xface->lte_frame_parms->frame_type == TDD) { //TDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
if (msi_pos == 4) {
msi_flag = 1;
}
if ( (frameP % mcch_period == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
} else { // FDD
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
case 9:
if (mac_xface->lte_frame_parms->frame_type == TDD) {
if ((eNB_mac_inst[module_idP].common_channels[CC_id].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 == eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
((eNB_mac_inst[module_idP].common_channels[CC_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) {
mcch_flag = 1;
}
mtch_flag = 1;
}
}
break;
}// end switch
// sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
module_idP, CC_id, frameP, subframeP,i,j,msi_flag,mcch_flag,mtch_flag);
break;
}
} else { // four-frameP format
}
}
} // end of for loop
eNB_mac_inst[module_idP].common_channels[CC_id].msi_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].mtch_active=0;
// Calculate the mcs
if ((msi_flag==1) || (mcch_flag==1)) {
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs = mcch_mcs;
}
else if (mtch_flag == 1) { // only MTCH in this subframeP
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs = eNB_mac_inst[module_idP].common_channels[CC_id].pmch_Config[0]->dataMCS_r9;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs = mcch_mcs;
} else if (mtch_flag == 1) { // only MTCH in this subframeP
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs = eNB_mac_inst[module_idP].common_channels[CC_id].pmch_Config[0]->dataMCS_r9;
}
@@ -309,257 +369,288 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
// there is MSI (MCH Scheduling Info)
if (msi_flag == 1) {
// Create MSI here
uint16_t msi_control_element[29], *msi_ptr;
// Create MSI here
uint16_t msi_control_element[29], *msi_ptr;
msi_ptr = &msi_control_element[0];
((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
if (mcch_flag==1) {
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0;
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0;
}
else { // no mcch for this MSP
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7;// stop value is 2047
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
}
msi_ptr+= sizeof(MSI_ELEMENT);
msi_ptr = &msi_control_element[0];
((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
//Header for MTCHs
num_mtch = eNB_mac_inst[module_idP].common_channels[CC_id].mbms_SessionList[0]->list.count;
for (k=0;k<num_mtch;k++) { // loop for all session in this MCH (MCH[0]) at this moment
((MSI_ELEMENT *) msi_ptr)->lcid = eNB_mac_inst[module_idP].common_channels[CC_id].mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9;//mtch_lcid;
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now)
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB;
msi_ptr+=sizeof(MSI_ELEMENT);
}
msi_length = msi_ptr-msi_control_element;
if (msi_length<128)
header_len_msi = 2;
else
header_len_msi = 3;
if (mcch_flag==1) {
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0;
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0;
} else { // no mcch for this MSP
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7;// stop value is 2047
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
}
LOG_D(MAC,"[eNB %d] Frame %d : MSI->MCH, length of MSI is %d bytes \n",module_idP,frameP,msi_length);
//LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" );
msi_ptr+= sizeof(MSI_ELEMENT);
// LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0]
memcpy((char *)&mch_buffer[sdu_length_total],
msi_control_element,
msi_length);
//Header for MTCHs
num_mtch = eNB_mac_inst[module_idP].common_channels[CC_id].mbms_SessionList[0]->list.count;
sdu_lcids[num_sdus] = MCH_SCHDL_INFO;
sdu_lengths[num_sdus] = msi_length;
sdu_length_total += sdu_lengths[num_sdus];
LOG_I(MAC,"[eNB %d] Create %d bytes for MSI\n",module_idP,sdu_lengths[num_sdus]);
num_sdus++;
eNB_mac_inst[module_idP].common_channels[CC_id].msi_active=1;
for (k=0; k<num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
((MSI_ELEMENT *) msi_ptr)->lcid = eNB_mac_inst[module_idP].common_channels[CC_id].mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9;//mtch_lcid;
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now)
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB;
msi_ptr+=sizeof(MSI_ELEMENT);
}
msi_length = msi_ptr-msi_control_element;
if (msi_length<128) {
header_len_msi = 2;
} else {
header_len_msi = 3;
}
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n",
module_idP,CC_id,frameP,msi_length);
//LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" );
// LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0]
memcpy((char *)&mch_buffer[sdu_length_total],
msi_control_element,
msi_length);
sdu_lcids[num_sdus] = MCH_SCHDL_INFO;
sdu_lengths[num_sdus] = msi_length;
sdu_length_total += sdu_lengths[num_sdus];
LOG_I(MAC,"[eNB %d] CC_id %d Create %d bytes for MSI\n", module_idP, CC_id, sdu_lengths[num_sdus]);
num_sdus++;
eNB_mac_inst[module_idP].common_channels[CC_id].msi_active=1;
}
// there is MCCH
if (mcch_flag == 1) {
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
module_idP,frameP, subframeP, i, j);
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
module_idP, CC_id, frameP, subframeP, i, j);
mcch_sdu_length = mac_rrc_data_req(module_idP,
frameP,
MCCH,1,
&eNB_mac_inst[module_idP].common_channels[CC_id].MCCH_pdu.payload[0],
1,// this is eNB
module_idP, // index
i); // this is the mbsfn sync area index
mcch_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
frameP,
MCCH,1,
&eNB_mac_inst[module_idP].common_channels[CC_id].MCCH_pdu.payload[0],
1,// this is eNB
module_idP, // index
i); // this is the mbsfn sync area index
if (mcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",module_idP,frameP,subframeP,mcch_sdu_length);
if (mcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",
module_idP,CC_id,frameP,subframeP,mcch_sdu_length);
header_len_mcch = 2;
if (mac_xface->lte_frame_parms->frame_type == TDD) {
LOG_D(MAC,"[eNB %d] Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
module_idP,
frameP,subframeP,
mcch_sdu_length,
mcch_mcs);
}
else {
LOG_I(MAC,"[eNB %d] Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
module_idP,
frameP, subframeP,
mcch_sdu_length,
mcch_mcs);
}
eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active=1;
header_len_mcch = 2;
memcpy((char *)&mch_buffer[sdu_length_total],
&eNB_mac_inst[module_idP].common_channels[CC_id].MCCH_pdu.payload[0],
mcch_sdu_length);
sdu_lcids[num_sdus] = MCCH_LCHANID;
sdu_lengths[num_sdus] = mcch_sdu_length;
if (sdu_lengths[num_sdus]>128)
header_len_mcch = 3;
sdu_length_total += sdu_lengths[num_sdus];
LOG_D(MAC,"[eNB %d] Got %d bytes for MCCH from RRC \n",module_idP,sdu_lengths[num_sdus]);
num_sdus++;
if (mac_xface->lte_frame_parms->frame_type == TDD) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
module_idP, CC_id,
frameP,subframeP,
mcch_sdu_length,
mcch_mcs);
} else {
LOG_I(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
module_idP, CC_id,
frameP, subframeP,
mcch_sdu_length,
mcch_mcs);
}
eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active=1;
memcpy((char *)&mch_buffer[sdu_length_total],
&eNB_mac_inst[module_idP].common_channels[CC_id].MCCH_pdu.payload[0],
mcch_sdu_length);
sdu_lcids[num_sdus] = MCCH_LCHANID;
sdu_lengths[num_sdus] = mcch_sdu_length;
if (sdu_lengths[num_sdus]>128) {
header_len_mcch = 3;
}
sdu_length_total += sdu_lengths[num_sdus];
LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",module_idP,CC_id,sdu_lengths[num_sdus]);
num_sdus++;
}
}
TBS = mac_xface->get_TBS_DL(eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs, mac_xface->lte_frame_parms->N_RB_DL);
#ifdef Rel10
// do not let mcch and mtch multiplexing when relaying is active
// for sync area 1, so not transmit data
//if ((i == 0) && ((eNB_mac_inst[module_idP].MBMS_flag != multicast_relay) || (eNB_mac_inst[module_idP].mcch_active==0))) {
#endif
// there is MTCHs, loop if there are more than 1
if (mtch_flag == 1) {
// Calculate TBS
/* if ((msi_flag==1) || (mcch_flag==1)) {
TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->lte_frame_parms->N_RB_DL);
}
else { // only MTCH in this subframeP
TBS = mac_xface->get_TBS(eNB_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9, mac_xface->lte_frame_parms->N_RB_DL);
}
// Calculate TBS
/* if ((msi_flag==1) || (mcch_flag==1)) {
TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->lte_frame_parms->N_RB_DL);
}
else { // only MTCH in this subframeP
TBS = mac_xface->get_TBS(eNB_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9, mac_xface->lte_frame_parms->N_RB_DL);
}
// get MTCH data from RLC (like for DTCH)
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,frame,subframe,i,j);
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j);
header_len_mtch = 3;
LOG_D(MAC,"[eNB %d], Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
Mod_id,frame,MTCH,TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
Mod_id,CC_id,frame,MTCH,TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer);
*/
*/
// get MTCH data from RLC (like for DTCH)
LOG_D(MAC,"[eNB %d] Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",module_idP,frameP,subframeP,i,j);
// get MTCH data from RLC (like for DTCH)
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",module_idP,CC_id,frameP,subframeP,i,j);
header_len_mtch = 3;
LOG_D(MAC,"[eNB %d], Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
module_idP,frameP,MTCH,TBS,
header_len_mtch = 3;
LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
module_idP,CC_id,frameP,MTCH,TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
rlc_status = mac_rlc_status_ind(module_idP,0,frameP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n",
MTCH,frameP,subframeP, rlc_status.bytes_in_buffer);
rlc_status = mac_rlc_status_ind(module_idP,0,frameP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n",
MTCH,frameP,subframeP, rlc_status.bytes_in_buffer);
if (rlc_status.bytes_in_buffer >0) {
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n",
module_idP,frameP,TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch,header_len_mtch);
if (rlc_status.bytes_in_buffer >0) {
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n",
module_idP,CC_id,frameP,TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch,header_len_mtch);
sdu_lengths[num_sdus] = mac_rlc_data_req(
module_idP,
0,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_YES,
MTCH,
(char*)&mch_buffer[sdu_length_total]);
//sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]);
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] Got %d bytes for MTCH %d\n",module_idP,sdu_lengths[num_sdus],MTCH);
eNB_mac_inst[module_idP].common_channels[CC_id].mtch_active=1;
sdu_lcids[num_sdus] = MTCH;
sdu_length_total += sdu_lengths[num_sdus];
if (sdu_lengths[num_sdus] < 128)
header_len_mtch = 2;
num_sdus++;
}
else {
header_len_mtch = 0;
sdu_lengths[num_sdus] = mac_rlc_data_req(
module_idP,
0,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_YES,
MTCH,
(char*)&mch_buffer[sdu_length_total]);
//sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]);
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",module_idP,CC_id,sdu_lengths[num_sdus],MTCH);
eNB_mac_inst[module_idP].common_channels[CC_id].mtch_active=1;
sdu_lcids[num_sdus] = MTCH;
sdu_length_total += sdu_lengths[num_sdus];
if (sdu_lengths[num_sdus] < 128) {
header_len_mtch = 2;
}
num_sdus++;
} else {
header_len_mtch = 0;
}
}
#ifdef Rel10
// }
#endif
// FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs
if ((sdu_length_total + header_len_msi + header_len_mcch + header_len_mtch) >0) {
// Adjust the last subheader
/* if ((msi_flag==1) || (mcch_flag==1)) {
eNB_mac_inst[module_idP].MCH_pdu.mcs = mcch_mcs;
}
else if (mtch_flag == 1) { // only MTCH in this subframeP
eNB_mac_inst[module_idP].MCH_pdu.mcs = eNB_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9;
}
*/
header_len_mtch_temp = header_len_mtch;
header_len_mcch_temp = header_len_mcch;
header_len_msi_temp = header_len_msi;
if (header_len_mtch>0)
header_len_mtch=1; // remove Length field in the subheader for the last PDU
else if (header_len_mcch>0)
header_len_mcch=1;
else header_len_msi=1;
// Calculate the padding
if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) < 0) {
LOG_E(MAC,"Error in building MAC PDU, TBS %d < PDU %d \n",
TBS, header_len_mtch + header_len_mcch + header_len_msi + sdu_length_total);
return;
}else if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) <= 2) {
padding = (TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total);
post_padding = 0;
}
else {// using post_padding, give back the Length field of subheader for the last PDU
padding = 0;
if (header_len_mtch>0)
header_len_mtch = header_len_mtch_temp;
else if (header_len_mcch>0)
header_len_mcch = header_len_mcch_temp;
else header_len_msi = header_len_msi_temp;
post_padding = TBS - sdu_length_total - header_len_msi - header_len_mcch - header_len_mtch;
}
// Generate the MAC Header for MCH
// here we use the function for DLSCH because DLSCH & MCH have the same Header structure
offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload,
num_sdus,
sdu_lengths,
sdu_lcids,
255, // no drx
0, // no timing advance
NULL, // no contention res id
padding,
post_padding);
// Adjust the last subheader
/* if ((msi_flag==1) || (mcch_flag==1)) {
eNB_mac_inst[module_idP].MCH_pdu.mcs = mcch_mcs;
}
else if (mtch_flag == 1) { // only MTCH in this subframeP
eNB_mac_inst[module_idP].MCH_pdu.mcs = eNB_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9;
}
*/
header_len_mtch_temp = header_len_mtch;
header_len_mcch_temp = header_len_mcch;
header_len_msi_temp = header_len_msi;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.Pdu_size=TBS;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.sync_area=i;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.msi_active= eNB_mac_inst[module_idP].common_channels[CC_id].msi_active;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active= eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active= eNB_mac_inst[module_idP].common_channels[CC_id].mtch_active;
LOG_D(MAC," MCS for this sf is %d (mcch active %d, mtch active %d)\n", eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs,
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active,eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active );
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE ] Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n",
module_idP,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,padding,post_padding,eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs,TBS,header_len_mtch, header_len_mcch, header_len_msi);
// copy SDU to mch_pdu after the MAC Header
memcpy(&eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload[offset],mch_buffer,sdu_length_total);
// filling remainder of MCH with random data if necessery
for (j=0;j<(TBS-sdu_length_total-offset);j++)
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
if (header_len_mtch>0) {
header_len_mtch=1; // remove Length field in the subheader for the last PDU
} else if (header_len_mcch>0) {
header_len_mcch=1;
} else {
header_len_msi=1;
}
#if defined(USER_MODE) && defined(OAI_EMU)
/* Tracing of PDU is done on UE side */
if (oai_emulation.info.opt_enabled)
trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload,
TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
eNB_mac_inst[module_idP].subframe,0,0);
LOG_D(OPT,"[eNB %d][MCH] Frame %d : MAC PDU with size %d\n",
module_idP, frameP, TBS);
#endif
/*
for (j=0;j<sdu_length_total;j++)
printf("%2x.",eNB_mac_inst[module_idP].MCH_pdu.payload[j+offset]);
printf(" \n");*/
return 1;
}
else {
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.Pdu_size=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.sync_area=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.msi_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active=0;
// for testing purpose, fill with random data
//for (j=0;j<(TBS-sdu_length_total-offset);j++)
// eNB_mac_inst[module_idP].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
// Calculate the padding
if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) < 0) {
LOG_E(MAC,"Error in building MAC PDU, TBS %d < PDU %d \n",
TBS, header_len_mtch + header_len_mcch + header_len_msi + sdu_length_total);
return 0;
} else if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) <= 2) {
padding = (TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total);
post_padding = 0;
} else { // using post_padding, give back the Length field of subheader for the last PDU
padding = 0;
if (header_len_mtch>0) {
header_len_mtch = header_len_mtch_temp;
} else if (header_len_mcch>0) {
header_len_mcch = header_len_mcch_temp;
} else {
header_len_msi = header_len_msi_temp;
}
post_padding = TBS - sdu_length_total - header_len_msi - header_len_mcch - header_len_mtch;
}
// Generate the MAC Header for MCH
// here we use the function for DLSCH because DLSCH & MCH have the same Header structure
offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload,
num_sdus,
sdu_lengths,
sdu_lcids,
255, // no drx
0, // no timing advance
NULL, // no contention res id
padding,
post_padding);
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.Pdu_size=TBS;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.sync_area=i;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.msi_active= eNB_mac_inst[module_idP].common_channels[CC_id].msi_active;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active= eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active= eNB_mac_inst[module_idP].common_channels[CC_id].mtch_active;
LOG_D(MAC," MCS for this sf is %d (mcch active %d, mtch active %d)\n", eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs,
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active,eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active );
LOG_I(MAC,
"[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n",
module_idP,CC_id,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,padding,post_padding,eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs,TBS,
header_len_mtch, header_len_mcch, header_len_msi);
// copy SDU to mch_pdu after the MAC Header
memcpy(&eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload[offset],mch_buffer,sdu_length_total);
// filling remainder of MCH with random data if necessery
for (j=0; j<(TBS-sdu_length_total-offset); j++) {
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
}
/* Tracing of PDU is done on UE side */
if (opt_enabled ==1 ) {
trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload,
TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
eNB_mac_inst[module_idP].subframe,0,0);
LOG_D(OPT,"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
module_idP, CC_id, frameP, TBS);
}
/*
for (j=0;j<sdu_length_total;j++)
printf("%2x.",eNB_mac_inst[module_idP].MCH_pdu.payload[j+offset]);
printf(" \n");*/
return 1;
} else {
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.Pdu_size=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.sync_area=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.msi_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcch_active=0;
eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mtch_active=0;
// for testing purpose, fill with random data
//for (j=0;j<(TBS-sdu_length_total-offset);j++)
// eNB_mac_inst[module_idP].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
return 0;
}
//this is for testing
/*
if (mtch_flag == 1) {
@@ -570,7 +661,9 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
return 0;
*/
}
MCH_PDU *get_mch_sdu(uint8_t module_idP, uint8_t CC_id, uint32_t frameP, sub_frame_t subframeP) {
MCH_PDU *get_mch_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframeP)
{
// eNB_mac_inst[module_idP].MCH_pdu.mcs=0;
//LOG_D(MAC," MCH_pdu.mcs is %d\n", eNB_mac_inst[module_idP].MCH_pdu.mcs);
#warning "MCH pdu should take the CC_id index"
+303 -206
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -68,20 +68,24 @@
#define DEBUG_eNB_SCHEDULER 1
void init_ue_sched_info(void){
//------------------------------------------------------------------------------
void init_ue_sched_info(void)
//------------------------------------------------------------------------------
{
module_id_t i,j,k;
for (i=0;i<NUMBER_OF_eNB_MAX;i++){
for (k=0;i<MAX_NUM_CCs;i++){
for (j=0;j<NUMBER_OF_UE_MAX;j++){
// init DL
eNB_dlsch_info[i][k][j].weight = 0;
eNB_dlsch_info[i][k][j].subframe = 0;
eNB_dlsch_info[i][k][j].serving_num = 0;
eNB_dlsch_info[i][k][j].status = S_DL_NONE;
// init UL
eNB_ulsch_info[i][k][j].subframe = 0;
eNB_ulsch_info[i][k][j].serving_num = 0;
eNB_ulsch_info[i][k][j].status = S_UL_NONE;
for (i=0; i<NUMBER_OF_eNB_MAX; i++) {
for (k=0; i<MAX_NUM_CCs; i++) {
for (j=0; j<NUMBER_OF_UE_MAX; j++) {
// init DL
eNB_dlsch_info[i][k][j].weight = 0;
eNB_dlsch_info[i][k][j].subframe = 0;
eNB_dlsch_info[i][k][j].serving_num = 0;
eNB_dlsch_info[i][k][j].status = S_DL_NONE;
// init UL
eNB_ulsch_info[i][k][j].subframe = 0;
eNB_ulsch_info[i][k][j].serving_num = 0;
eNB_ulsch_info[i][k][j].status = S_UL_NONE;
}
}
}
@@ -89,52 +93,76 @@ void init_ue_sched_info(void){
unsigned char get_ue_weight(module_id_t module_idP, int CC_id, int ue_idP){
//------------------------------------------------------------------------------
unsigned char get_ue_weight(module_id_t module_idP, int CC_id, int ue_idP)
//------------------------------------------------------------------------------
{
return(eNB_dlsch_info[module_idP][CC_id][ue_idP].weight);
}
DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframeP) {
//------------------------------------------------------------------------------
DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframeP)
//------------------------------------------------------------------------------
{
return(&eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu);
}
int find_UE_id(module_id_t mod_idP, rnti_t rntiP) {
//------------------------------------------------------------------------------
int find_UE_id(module_id_t mod_idP, rnti_t rntiP)
//------------------------------------------------------------------------------
{
int UE_id;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
return(UE_id);
}
}
return(-1);
}
int UE_num_active_CC(UE_list_t *listP,int ue_idP) {
//------------------------------------------------------------------------------
int UE_num_active_CC(UE_list_t *listP,int ue_idP)
//------------------------------------------------------------------------------
{
return(listP->numactiveCCs[ue_idP]);
}
int UE_PCCID(module_id_t mod_idP,int ue_idP) {
//------------------------------------------------------------------------------
int UE_PCCID(module_id_t mod_idP,int ue_idP)
//------------------------------------------------------------------------------
{
return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]);
}
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) {
//------------------------------------------------------------------------------
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP)
//------------------------------------------------------------------------------
{
rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti;
if (rnti>0)
if (rnti>0) {
return (rnti);
LOG_W(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP);
//mac_xface->macphy_exit("UE_RNTI: Couldn't find RNTI for UE");
return(0);
}
LOG_E(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP);
//display_backtrace();
return(NOT_A_RNTI);
}
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP){
//------------------------------------------------------------------------------
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP)
//------------------------------------------------------------------------------
{
return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
}
@@ -150,10 +178,10 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].ul_active==TRUE)){
if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
nb_active_ue++;
nb_active_ue++;
}
else { // this ue is removed at the phy => remove it at the mac as well
mac_remove_ue(module_idP, CC_id, ue_mod_id);
mac_remove_ue(module_idP, CC_id, ue_mod_id);
}
}
}
@@ -163,7 +191,8 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
// get aggregatiob form phy for a give UE
unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP) {
unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP)
{
unsigned char aggregation=2;
// check the MCS and SNR and set the aggregation accordingly
return aggregation;
@@ -182,13 +211,13 @@ uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsign
if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].rnti) !=0) &&
(eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].ul_active==TRUE) &&
(mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
// && (UE_is_to_be_scheduled(module_idP,UE_id)))
// check at the phy enb_ue state for this rnti
if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti)) != NULL){
if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
nb_ue_in_pusch++;
}
}
// && (UE_is_to_be_scheduled(module_idP,UE_id)))
// check at the phy enb_ue state for this rnti
if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti)) != NULL){
if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
nb_ue_in_pusch++;
}
}
}
}
return(nb_ue_in_pusch);
@@ -196,30 +225,34 @@ uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsign
*/
#endif
void dump_ue_list(UE_list_t *listP, int ul_flag) {
void dump_ue_list(UE_list_t *listP, int ul_flag)
{
int j;
if ( ul_flag == 0 ){
for (j=listP->head;j>=0;j=listP->next[j]) {
if ( ul_flag == 0 ) {
for (j=listP->head; j>=0; j=listP->next[j]) {
LOG_T(MAC,"node %d => %d\n",j,listP->next[j]);
}
} else {
for (j=listP->head_ul;j>=0;j=listP->next_ul[j]) {
for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
LOG_T(MAC,"node %d => %d\n",j,listP->next_ul[j]);
}
}
}
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
{
int UE_id;
int j;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs);
dump_ue_list(UE_list,0);
if (UE_list->avail>=0) {
UE_id = UE_list->avail;
AssertFatal( UE_id < NUMBER_OF_UE_MAX, "BAD UE_id %u > NUMBER_OF_UE_MAX",UE_id );
UE_list->avail = UE_list->next[UE_list->avail];
UE_list->next[UE_id] = UE_list->head;
UE_list->next_ul[UE_id] = UE_list->head_ul;
@@ -235,12 +268,13 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
UE_list->num_UEs++;
UE_list->active[UE_id] = TRUE;
for (j=0;j<8;j++) {
UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j==0)?1:0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0
for (j=0; j<8; j++) {
UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j==0)?1:0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0
UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j==harq_pidP)?0:1; // 1st transmission is with Msg3;
}
eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING;
LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP);
dump_ue_list(UE_list,0);
return(UE_id);
@@ -251,14 +285,19 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
return(-1);
}
int mac_remove_ue(module_id_t mod_idP, int ue_idP, int frameP) {
//------------------------------------------------------------------------------
int mac_remove_ue(module_id_t mod_idP, int ue_idP, int frameP, sub_frame_t subframeP)
//------------------------------------------------------------------------------
{
int prev,i, ret=-1;
rnti_t rnti;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
int pCC_id = UE_PCCID(mod_idP,ue_idP);
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",ue_idP,pCC_id, UE_list->UE_template[pCC_id][ue_idP].rnti);
rnti = UE_list->UE_template[pCC_id][ue_idP].rnti;
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",ue_idP,pCC_id, rnti);
dump_ue_list(UE_list,0);
// clear all remaining pending transmissions
@@ -268,92 +307,113 @@ int mac_remove_ue(module_id_t mod_idP, int ue_idP, int frameP) {
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][ue_idP].ul_SR = 0;
UE_list->UE_template[pCC_id][ue_idP].rnti = 0;
UE_list->UE_template[pCC_id][ue_idP].rnti = NOT_A_RNTI;
UE_list->UE_template[pCC_id][ue_idP].ul_active = FALSE;
eNB_ulsch_info[mod_idP][pCC_id][ue_idP].rnti = 0;
eNB_ulsch_info[mod_idP][pCC_id][ue_idP].rnti = NOT_A_RNTI;
eNB_ulsch_info[mod_idP][pCC_id][ue_idP].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][pCC_id][ue_idP].rnti = 0;
eNB_dlsch_info[mod_idP][pCC_id][ue_idP].rnti = NOT_A_RNTI;
eNB_dlsch_info[mod_idP][pCC_id][ue_idP].status = S_DL_NONE;
rrc_eNB_free_UE_index(mod_idP,ue_idP,frameP);
rrc_eNB_free_UE(
mod_idP,
rnti,
frameP,
subframeP);
prev = UE_list->head;
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
if (i == ue_idP) {
// link prev to next in Active list
//if (prev==UE_list->head)
if (i==UE_list->head)
UE_list->head = UE_list->next[i];
else
UE_list->next[prev] = UE_list->next[i];
// add UE id (i)to available
//if (prev==UE_list->head)
if (i==UE_list->head) {
UE_list->head = UE_list->next[i];
} else {
UE_list->next[prev] = UE_list->next[i];
}
// add UE id (i)to available
UE_list->next[i] = UE_list->avail;
UE_list->avail = i;
UE_list->active[i] = FALSE;
UE_list->num_UEs--;
UE_list->num_UEs--;
ret=0;
break;
}
prev=i;
}
// do the same for UL
prev = UE_list->head_ul;
for (i=UE_list->head_ul;i>=0;i=UE_list->next_ul[i]) {
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
if (i == ue_idP) {
// link prev to next in Active list
if (prev==UE_list->head_ul)
UE_list->head_ul = UE_list->next_ul[i];
else
UE_list->next_ul[prev] = UE_list->next_ul[i];
// add UE id (i)to available
if (prev==UE_list->head_ul) {
UE_list->head_ul = UE_list->next_ul[i];
} else {
UE_list->next_ul[prev] = UE_list->next_ul[i];
}
// add UE id (i)to available
UE_list->next_ul[i] = UE_list->avail;
ret = 0;
break;
}
prev=i;
}
if (ret == 0)
if (ret == 0) {
return (0);
}
LOG_E(MAC,"error in mac_remove_ue(), could not find previous to %d in UE_list, should never happen, Dumping UE list\n",ue_idP);
dump_ue_list(UE_list,0);
mac_xface->macphy_exit("mac_remove_ue: Problem in UE_list");
mac_xface->macphy_exit("mac_remove_ue: Problem in UE_list");
return(-1);
}
int prev(UE_list_t *listP, int nodeP, int ul_flag) {
int prev(UE_list_t *listP, int nodeP, int ul_flag)
{
int j;
if (ul_flag == 0 ) {
if (nodeP==listP->head)
if (nodeP==listP->head) {
return(nodeP);
for (j=listP->head;j>=0;j=listP->next[j]) {
if (listP->next[j]==nodeP)
return(j);
}
for (j=listP->head; j>=0; j=listP->next[j]) {
if (listP->next[j]==nodeP) {
return(j);
}
}
} else {
if (nodeP==listP->head_ul)
if (nodeP==listP->head_ul) {
return(nodeP);
for (j=listP->head_ul;j>=0;j=listP->next_ul[j]) {
if (listP->next_ul[j]==nodeP)
return(j);
}
for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
if (listP->next_ul[j]==nodeP) {
return(j);
}
}
}
LOG_E(MAC,"error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
nodeP, (ul_flag == 0)? "DL" : "UL");
nodeP, (ul_flag == 0)? "DL" : "UL");
dump_ue_list(listP, ul_flag);
return(-1);
}
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag) {
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag)
{
int prev_i,prev_j,next_i,next_j;
@@ -362,12 +422,13 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag) {
prev_i = prev(listP,nodeiP,ul_flag);
prev_j = prev(listP,nodejP,ul_flag);
if ((prev_i<0) || (prev_j<0)) {
mac_xface->macphy_exit("swap_UEs: problem");
return; // not reached
}
if (ul_flag == 0){
if (ul_flag == 0) {
next_i = listP->next[nodeiP];
next_j = listP->next[nodejP];
} else {
@@ -376,111 +437,112 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag) {
}
LOG_T(MAC,"[%s] next_i %d, next_i, next_j %d, head %d \n",
(ul_flag == 0)? "DL" : "UL",
next_i,next_j,listP->head);
(ul_flag == 0)? "DL" : "UL",
next_i,next_j,listP->head);
if (ul_flag == 0 ) {
if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
LOG_T(MAC,"Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
listP->next[nodeiP] = next_j;
listP->next[nodejP] = nodeiP;
if (nodeiP==listP->head) // case i j n(j)
listP->head = nodejP;
else
listP->next[prev_i] = nodejP;
}
else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
if (nodeiP==listP->head) { // case i j n(j)
listP->head = nodejP;
} else {
listP->next[prev_i] = nodejP;
}
} else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
LOG_T(MAC,"Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
listP->next[nodejP] = next_i;
listP->next[nodeiP] = nodejP;
if (nodejP==listP->head) // case j i n(i)
listP->head = nodeiP;
else
listP->next[prev_j] = nodeiP;
}
else { // case ... p(i) i n(i) ... p(j) j n(j) ...
if (nodejP==listP->head) { // case j i n(i)
listP->head = nodeiP;
} else {
listP->next[prev_j] = nodeiP;
}
} else { // case ... p(i) i n(i) ... p(j) j n(j) ...
listP->next[nodejP] = next_i;
listP->next[nodeiP] = next_j;
if (nodeiP==listP->head) {
LOG_T(MAC,"changing head to %d\n",nodejP);
listP->head=nodejP;
listP->next[prev_j] = nodeiP;
}
else if (nodejP==listP->head){
LOG_D(MAC,"changing head to %d\n",nodeiP);
listP->head=nodeiP;
listP->next[prev_i] = nodejP;
}
else {
listP->next[prev_i] = nodejP;
listP->next[prev_j] = nodeiP;
LOG_T(MAC,"changing head to %d\n",nodejP);
listP->head=nodejP;
listP->next[prev_j] = nodeiP;
} else if (nodejP==listP->head) {
LOG_D(MAC,"changing head to %d\n",nodeiP);
listP->head=nodeiP;
listP->next[prev_i] = nodejP;
} else {
listP->next[prev_i] = nodejP;
listP->next[prev_j] = nodeiP;
}
}
} else { // ul_flag
if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
LOG_T(MAC,"[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
listP->next_ul[nodeiP] = next_j;
listP->next_ul[nodejP] = nodeiP;
if (nodeiP==listP->head_ul) // case i j n(j)
listP->head_ul = nodejP;
else
listP->next_ul[prev_i] = nodejP;
}
else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
if (nodeiP==listP->head_ul) { // case i j n(j)
listP->head_ul = nodejP;
} else {
listP->next_ul[prev_i] = nodejP;
}
} else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
LOG_T(MAC,"[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
listP->next_ul[nodejP] = next_i;
listP->next_ul[nodeiP] = nodejP;
if (nodejP==listP->head_ul) // case j i n(i)
listP->head_ul = nodeiP;
else
listP->next_ul[prev_j] = nodeiP;
}
else { // case ... p(i) i n(i) ... p(j) j n(j) ...
if (nodejP==listP->head_ul) { // case j i n(i)
listP->head_ul = nodeiP;
} else {
listP->next_ul[prev_j] = nodeiP;
}
} else { // case ... p(i) i n(i) ... p(j) j n(j) ...
listP->next_ul[nodejP] = next_i;
listP->next_ul[nodeiP] = next_j;
if (nodeiP==listP->head_ul) {
LOG_T(MAC,"[UL]changing head to %d\n",nodejP);
listP->head_ul=nodejP;
listP->next_ul[prev_j] = nodeiP;
}
else if (nodejP==listP->head_ul){
LOG_T(MAC,"[UL]changing head to %d\n",nodeiP);
listP->head_ul=nodeiP;
listP->next_ul[prev_i] = nodejP;
}
else {
listP->next_ul[prev_i] = nodejP;
listP->next_ul[prev_j] = nodeiP;
LOG_T(MAC,"[UL]changing head to %d\n",nodejP);
listP->head_ul=nodejP;
listP->next_ul[prev_j] = nodeiP;
} else if (nodejP==listP->head_ul) {
LOG_T(MAC,"[UL]changing head to %d\n",nodeiP);
listP->head_ul=nodeiP;
listP->next_ul[prev_i] = nodejP;
} else {
listP->next_ul[prev_i] = nodejP;
listP->next_ul[prev_j] = nodeiP;
}
}
}
LOG_T(MAC,"After swap\n");
dump_ue_list(listP,ul_flag);
}
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) {
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
{
int UE_id = find_UE_id(mod_idP, rntiP);
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
if (UE_id != -1) {
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
} else {
// AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
// AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) \n",mod_idP,rntiP,frameP,subframeP, UE_id);
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
}
}
@@ -600,13 +662,14 @@ void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP
#endif
*/
void add_common_dci(DCI_PDU *DCI_pdu,
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t ra_flag) {
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t ra_flag)
{
memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_pdu[0],pdu,dci_size_bytes);
DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_length = dci_size_bits;
@@ -620,7 +683,8 @@ void add_common_dci(DCI_PDU *DCI_pdu,
LOG_D(MAC,"add common dci format %d for rnti %x \n",dci_fmt,rnti);
}
void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag) {
void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag)
{
memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_pdu[0],pdu,dci_size_bytes);
DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_length = dci_size_bits;
@@ -639,113 +703,138 @@ void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_si
// This has to be updated to include BSR information
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id) {
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
{
UE_TEMPLATE *UE_template = &eNB_mac_inst[module_idP].UE_list.UE_template[CC_id][UE_id];
// LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframeP %d Scheduling UE %d\n",module_idP,rnti,frameP,subframeP,
// UE_id);
// UE_id);
if ((UE_template->bsr_info[LCGID0]>0) ||
(UE_template->bsr_info[LCGID1]>0) ||
(UE_template->bsr_info[LCGID2]>0) ||
(UE_template->bsr_info[LCGID3]>0) ||
(UE_template->ul_SR>0)) // uplink scheduling request
(UE_template->ul_SR>0)) { // uplink scheduling request
return(1);
else
} else {
return(0);
}
}
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc) {
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc)
{
int i;
uint32_t rballoc_dci=0;
unsigned char nb_rb_alloc=0;
for (i=0;i<(mac_xface->lte_frame_parms->N_RB_DL-2);i+=2) {
if (((*rballoc>>i)&3)==0) {
*rballoc |= (3<<i);
rballoc_dci |= (1<<((12-i)>>1));
nb_rb_alloc+=2;
}
if (nb_rb_alloc==nb_rb)
return(rballoc_dci);
for (i=0; i<(mac_xface->lte_frame_parms->N_RB_DL-2); i+=2) {
if (((*rballoc>>i)&3)==0) {
*rballoc |= (3<<i);
rballoc_dci |= (1<<((12-i)>>1));
nb_rb_alloc+=2;
}
if (nb_rb_alloc==nb_rb) {
return(rballoc_dci);
}
}
if ((mac_xface->lte_frame_parms->N_RB_DL&1)==1) {
if ((*rballoc>>(mac_xface->lte_frame_parms->N_RB_DL-1)&1)==0) {
*rballoc |= (1<<(mac_xface->lte_frame_parms->N_RB_DL-1));
rballoc_dci |= 1;//(1<<(mac_xface->lte_frame_parms->N_RB_DL>>1));
}
if ((*rballoc>>(mac_xface->lte_frame_parms->N_RB_DL-1)&1)==0) {
*rballoc |= (1<<(mac_xface->lte_frame_parms->N_RB_DL-1));
rballoc_dci |= 1;//(1<<(mac_xface->lte_frame_parms->N_RB_DL>>1));
}
}
return(rballoc_dci);
}
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id){
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id)
{
int min_rb_unit=0;
LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);
LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);
switch (frame_parms->N_RB_DL) {
case 6: // 1.4 MHz
min_rb_unit=1;
break;
case 25: // 5HMz
min_rb_unit=2;
break;
case 50: // 10HMz
min_rb_unit=3;
break;
case 100: // 20HMz
min_rb_unit=4;
break;
default:
min_rb_unit=2;
LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", module_id, CC_id);
break;
}
return min_rb_unit;
}
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc) {
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc)
{
int check=0;//check1=0,check2=0;
uint32_t rballoc_dci=0;
//uint8_t number_of_subbands=13;
LOG_T(MAC,"*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n",
rballoc[3],rballoc[2],rballoc[1],rballoc[0],nb_rb,mac_xface->lte_frame_parms->N_RBG);
while((nb_rb >0) && (check < mac_xface->lte_frame_parms->N_RBG)){
rballoc[3],rballoc[2],rballoc[1],rballoc[0],nb_rb,mac_xface->lte_frame_parms->N_RBG);
while((nb_rb >0) && (check < mac_xface->lte_frame_parms->N_RBG)) {
//printf("rballoc[%d] %d\n",check,rballoc[check]);
if(rballoc[check] == 1){
rballoc_dci |= (1<<((mac_xface->lte_frame_parms->N_RBG-1)-check));
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
nb_rb--;
break;
case 25:
if ((check == mac_xface->lte_frame_parms->N_RBG-1))
nb_rb--;
else
nb_rb-=2;
break;
case 50:
if ((check == mac_xface->lte_frame_parms->N_RBG-1))
nb_rb-=2;
else
nb_rb-=3;
break;
case 100:
nb_rb-=4;
break;
}
if(rballoc[check] == 1) {
rballoc_dci |= (1<<((mac_xface->lte_frame_parms->N_RBG-1)-check));
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
nb_rb--;
break;
case 25:
if ((check == mac_xface->lte_frame_parms->N_RBG-1)) {
nb_rb--;
} else {
nb_rb-=2;
}
break;
case 50:
if ((check == mac_xface->lte_frame_parms->N_RBG-1)) {
nb_rb-=2;
} else {
nb_rb-=3;
}
break;
case 100:
nb_rb-=4;
break;
}
// printf("rb_alloc %x\n",rballoc_dci);
check = check+1;
// check1 = check1+2;
}
// printf("rb_alloc %x\n",rballoc_dci);
check = check+1;
// check1 = check1+2;
}
// rballoc_dci = (rballoc_dci)&(0x1fff);
LOG_T(MAC,"*********RBALLOC : %x\n",rballoc_dci);
// exit(-1);
@@ -753,32 +842,40 @@ uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc) {
}
int get_nb_subband(void){
int get_nb_subband(void)
{
int nb_sb=0;
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
nb_sb=0;
nb_sb=0;
break;
case 15:
nb_sb = 4; // sb_size =4
case 25:
case 25:
nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs
break;
case 50: // sb_size =6
nb_sb = 9;
break;
case 75: // sb_size =8
nb_sb = 10;
break;
case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs
nb_sb = 13;
break;
default:
nb_sb=0;
break;
}
return nb_sb;
}
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -59,8 +59,8 @@ extern eNB_MAC_INST *eNB_mac_inst;
extern MAC_RLC_XFACE *Mac_rlc_xface;
extern uint8_t Is_rrc_registered;
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
@@ -80,7 +80,7 @@ extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern unsigned char NB_RN_INST;
extern unsigned short NODE_ID[1];
extern void* bigphys_malloc(int);
extern void* bigphys_malloc(int);
#else
extern EMULATION_VARS *Emul_vars;
#endif //PHY_EMUL
+10 -7
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -41,7 +41,8 @@
#include "UTIL/LOG/log.h"
#include "proto.h"
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id) {
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id)
{
RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
if (CC_id>0) {
@@ -50,18 +51,20 @@ int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id) {
return 0; // not reached
}
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
}
else {
LOG_E(MAC,"[UE %d] CCid %d FATAL radioResourceConfigCommon is NULL !!!\n",module_idP,CC_id);
mac_xface->macphy_exit("FATAL radioResourceConfigCommon is NULL");
}
return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) +
get_DELTA_PREAMBLE(module_idP,CC_id));
return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) +
get_DELTA_PREAMBLE(module_idP,CC_id));
}
int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id) {
int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id)
{
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
@@ -71,5 +74,5 @@ int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id) {
LOG_D(MAC,"[PUSCH]%d dB\n",UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1);
return((int8_t)(UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1));
}
+14 -10
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -34,10 +34,11 @@
#include "extern.h"
void init_transport_channels(unsigned char transmission_mode) {
void init_transport_channels(unsigned char transmission_mode)
{
// init DCI structures for testing
UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0;
UL_alloc_pdu.rballoc = UL_RB_ALLOC;
@@ -45,7 +46,7 @@ void init_transport_channels(unsigned char transmission_mode) {
UL_alloc_pdu.ndi = 1;
UL_alloc_pdu.TPC = 0;
UL_alloc_pdu.cqi_req = 1;
/*
BCCH_alloc_pdu.type = 1;
BCCH_alloc_pdu.vrb_type = 0;
@@ -103,7 +104,7 @@ void init_transport_channels(unsigned char transmission_mode) {
RA_alloc_pdu_fdd.harq_pid = 0;
RA_alloc_pdu_fdd.TPC = 1;
DLSCH_alloc_pdu1.rballoc = 0xf;
DLSCH_alloc_pdu1.TPC = 0;
DLSCH_alloc_pdu1.dai = 0;
@@ -112,11 +113,13 @@ void init_transport_channels(unsigned char transmission_mode) {
DLSCH_alloc_pdu1.mcs1 = 4;
DLSCH_alloc_pdu1.ndi1 = 1;
DLSCH_alloc_pdu1.rv1 = 0;
// Forget second codeword
if (transmission_mode == 6)
if (transmission_mode == 6) {
DLSCH_alloc_pdu1.tpmi = 5; // PUSCH_PRECODING0
else
} else {
DLSCH_alloc_pdu1.tpmi = 0;
}
DLSCH_alloc_pdu2.rah = 0;
DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC;
@@ -127,10 +130,11 @@ void init_transport_channels(unsigned char transmission_mode) {
DLSCH_alloc_pdu2.mcs1 = 4;
DLSCH_alloc_pdu2.ndi1 = 1;
DLSCH_alloc_pdu2.rv1 = 0;
// Forget second codeword
if (transmission_mode == 6)
if (transmission_mode == 6) {
DLSCH_alloc_pdu2.tpmi = 5; // PUSCH_PRECODING0
else
} else {
DLSCH_alloc_pdu2.tpmi = 0;
}
}
+191 -151
View File
@@ -21,14 +21,14 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file main.c
* \brief top init of Layer 2
* \author Navid Nikaein and Raymond Knopp
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 1.0
* \email: navid.nikaein@eurecom.fr
@@ -71,48 +71,54 @@
#include "SCHED/defs.h"
void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP,
unsigned char eNB_index,
uint8_t first_sync){ //init as MR
frame_t frameP,
unsigned char eNB_index,
uint8_t first_sync) //init as MR
{
LOG_D(MAC,"[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index);
#if ! defined(ENABLE_USE_MME)
if (first_sync==1) {
layer2_init_UE(module_idP);
openair_rrc_ue_init(module_idP,eNB_index);
}
else
layer2_init_UE(module_idP);
openair_rrc_ue_init(module_idP,eNB_index);
} else
#endif
{
mac_in_sync_ind(module_idP,frameP,eNB_index);
mac_in_sync_ind(module_idP,frameP,eNB_index);
}
}
void mrbch_phy_sync_failure(module_id_t module_idP, frame_t frameP, uint8_t free_eNB_index){//init as CH
void mrbch_phy_sync_failure(module_id_t module_idP, frame_t frameP, uint8_t free_eNB_index) //init as CH
{
LOG_I(MAC,"[eNB %d] Frame %d: PHY Sync failure \n",module_idP,frameP);
layer2_init_eNB(module_idP, free_eNB_index);
openair_rrc_eNB_init(module_idP);
}
char layer2_init_eNB(module_id_t module_idP, unsigned char eNB_index){
char layer2_init_eNB(module_id_t module_idP, unsigned char eNB_index)
{
return 0;
}
char layer2_init_UE(module_id_t module_idP){
char layer2_init_UE(module_id_t module_idP)
{
return 0;
}
void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t eNB_index){
void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t eNB_index)
{
// Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index);
}
int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active){
int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active)
{
module_id_t Mod_id,i,j;
RA_TEMPLATE *RA_template;
@@ -123,74 +129,82 @@ int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ui
UE_list_t *UE_list;
LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST);
if (NB_UE_INST>0) {
UE_mac_inst = (UE_MAC_INST*)malloc16(NB_UE_INST*sizeof(UE_MAC_INST));
if (UE_mac_inst == NULL) {
LOG_C(MAC,"[MAIN] Can't ALLOCATE %d Bytes for %d UE_MAC_INST with size %d \n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,sizeof(UE_MAC_INST));
mac_xface->macphy_exit("[MAC][MAIN] not enough memory for UEs \n");
}
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d UE_MAC_INST @ %p\n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,UE_mac_inst);
UE_mac_inst = (UE_MAC_INST*)malloc16(NB_UE_INST*sizeof(UE_MAC_INST));
bzero(UE_mac_inst,NB_UE_INST*sizeof(UE_MAC_INST));
for(i=0;i<NB_UE_INST; i++)
ue_init_mac(i);
if (UE_mac_inst == NULL) {
LOG_C(MAC,"[MAIN] Can't ALLOCATE %d Bytes for %d UE_MAC_INST with size %d \n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,sizeof(UE_MAC_INST));
mac_xface->macphy_exit("[MAC][MAIN] not enough memory for UEs \n");
}
}
else
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d UE_MAC_INST @ %p\n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,UE_mac_inst);
bzero(UE_mac_inst,NB_UE_INST*sizeof(UE_MAC_INST));
for(i=0; i<NB_UE_INST; i++) {
ue_init_mac(i);
}
} else {
UE_mac_inst = NULL;
}
LOG_I(MAC,"[MAIN] Init function start:Nb_eNB_INST=%d\n",NB_eNB_INST);
if (NB_eNB_INST>0) {
eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST));
if (eNB_mac_inst == NULL){
LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST*),NB_eNB_INST,sizeof(eNB_MAC_INST));
mac_xface->macphy_exit("[MAC][MAIN] not enough memory for eNB \n");
}
else{
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst);
bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST));
}
}
else
eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST));
if (eNB_mac_inst == NULL) {
LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST*),NB_eNB_INST,sizeof(eNB_MAC_INST));
mac_xface->macphy_exit("[MAC][MAIN] not enough memory for eNB \n");
} else {
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst);
bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST));
}
} else {
eNB_mac_inst = NULL;
}
// Initialize Linked-List for Active UEs
for(Mod_id=0;Mod_id<NB_eNB_INST;Mod_id++){
for(Mod_id=0; Mod_id<NB_eNB_INST; Mod_id++) {
UE_list = &eNB_mac_inst[Mod_id].UE_list;
UE_list->num_UEs=0;
UE_list->head=-1;
UE_list->head_ul=-1;
UE_list->head_ul=-1;
UE_list->avail=0;
for (list_el=0;list_el<NUMBER_OF_UE_MAX-1;list_el++) {
for (list_el=0; list_el<NUMBER_OF_UE_MAX-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;
#ifdef PHY_EMUL
Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR
#endif
/*#ifdef Rel10
/*#ifdef Rel10
int n;
for (n=0;n<4096;n++)
eNB_mac_inst[Mod_id].MCH_pdu.payload[n] = taus();
eNB_mac_inst[Mod_id].MCH_pdu.payload[n] = taus();
// Mac_rlc_xface->Node_id[Mod_id]=NODE_ID[Mod_id];
#endif*/
}
// Mac_rlc_xface->frame=Mac_rlc_xface->frame;
if (Is_rrc_registered == 1){
LOG_I(MAC,"[MAIN] calling RRC\n");
if (Is_rrc_registered == 1) {
LOG_I(MAC,"[MAIN] calling RRC\n");
#ifndef CELLULAR //nothing to be done yet for cellular
openair_rrc_top_init(eMBMS_active, uecap_xer, cba_group_active,HO_active);
openair_rrc_top_init(eMBMS_active, uecap_xer, cba_group_active,HO_active);
#endif
} else {
LOG_I(MAC,"[MAIN] Running without an RRC\n");
}
else {
LOG_I(MAC,"[MAIN] Running without an RRC\n");
}
#ifndef USER_MODE
#ifndef PHY_EMUL
LOG_I(MAC,"[MAIN] add openair2 proc\n");
@@ -202,99 +216,109 @@ int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ui
// Set up DCIs for TDD 5MHz Config 1..6
for (i=0;i<NB_eNB_INST;i++)
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
LOG_D(MAC,"[MAIN][eNB %d] initializing RA_template\n",i);
for (i=0; i<NB_eNB_INST; i++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
LOG_D(MAC,"[MAIN][eNB %d] CC_id %d initializing RA_template\n",i, CC_id);
LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", i);
RA_template = (RA_TEMPLATE *)&eNB_mac_inst[i].common_channels[CC_id].RA_template[0];
for (j=0;j<NB_RA_PROC_MAX;j++) {
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
case 25:
size_bytes1 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_5MHz_TDD_1_6_t;
break;
case 50:
size_bytes1 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_10MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_10MHz_TDD_1_6_t;
break;
case 100:
size_bytes1 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_20MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_20MHz_TDD_1_6_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
}
}
else {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
case 25:
size_bytes1 = sizeof(DCI1A_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_5MHz_FDD_t;
break;
case 50:
size_bytes1 = sizeof(DCI1A_10MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_10MHz_FDD_t);
size_bits1 = sizeof_DCI1A_10MHz_FDD_t;
size_bits2 = sizeof_DCI1A_10MHz_FDD_t;
break;
case 100:
size_bytes1 = sizeof(DCI1A_20MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_20MHz_FDD_t);
size_bits1 = sizeof_DCI1A_20MHz_FDD_t;
size_bits2 = sizeof_DCI1A_20MHz_FDD_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
}
}
memcpy((void *)&RA_template[j].RA_alloc_pdu1[0],(void *)&RA_alloc_pdu,size_bytes1);
memcpy((void *)&RA_template[j].RA_alloc_pdu2[0],(void *)&DLSCH_alloc_pdu1A,size_bytes2);
RA_template[j].RA_dci_size_bytes1 = size_bytes1;
RA_template[j].RA_dci_size_bytes2 = size_bytes2;
RA_template[j].RA_dci_size_bits1 = size_bits1;
RA_template[j].RA_dci_size_bits2 = size_bits2;
for (j=0; j<NB_RA_PROC_MAX; j++) {
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
RA_template[j].RA_dci_fmt1 = format1A;
RA_template[j].RA_dci_fmt2 = format1A;
case 25:
size_bytes1 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_5MHz_TDD_1_6_t;
break;
case 50:
size_bytes1 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_10MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_10MHz_TDD_1_6_t;
break;
case 100:
size_bytes1 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_20MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_20MHz_TDD_1_6_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
}
} else {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
case 25:
size_bytes1 = sizeof(DCI1A_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_5MHz_FDD_t;
break;
case 50:
size_bytes1 = sizeof(DCI1A_10MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_10MHz_FDD_t);
size_bits1 = sizeof_DCI1A_10MHz_FDD_t;
size_bits2 = sizeof_DCI1A_10MHz_FDD_t;
break;
case 100:
size_bytes1 = sizeof(DCI1A_20MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_20MHz_FDD_t);
size_bits1 = sizeof_DCI1A_20MHz_FDD_t;
size_bits2 = sizeof_DCI1A_20MHz_FDD_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
}
}
memcpy((void *)&RA_template[j].RA_alloc_pdu1[0],(void *)&RA_alloc_pdu,size_bytes1);
memcpy((void *)&RA_template[j].RA_alloc_pdu2[0],(void *)&DLSCH_alloc_pdu1A,size_bytes2);
RA_template[j].RA_dci_size_bytes1 = size_bytes1;
RA_template[j].RA_dci_size_bytes2 = size_bytes2;
RA_template[j].RA_dci_size_bits1 = size_bits1;
RA_template[j].RA_dci_size_bits2 = size_bits2;
RA_template[j].RA_dci_fmt1 = format1A;
RA_template[j].RA_dci_fmt2 = format1A;
}
memset (&eNB_mac_inst[i].eNB_stats,0,sizeof(eNB_STATS));
UE_template = (UE_TEMPLATE *)&eNB_mac_inst[i].UE_list.UE_template[CC_id][0];
for (j=0;j<NUMBER_OF_UE_MAX;j++) {
UE_template[j].rnti=0;
// initiallize the eNB to UE statistics
memset (&eNB_mac_inst[i].UE_list.eNB_UE_stats[CC_id][j],0,sizeof(eNB_UE_STATS));
for (j=0; j<NUMBER_OF_UE_MAX; j++) {
UE_template[j].rnti=0;
// initiallize the eNB to UE statistics
memset (&eNB_mac_inst[i].UE_list.eNB_UE_stats[CC_id][j],0,sizeof(eNB_UE_STATS));
}
}
@@ -306,18 +330,21 @@ int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ui
srand (time(NULL));
for(j=0;j<NB_eNB_INST;j++)
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
for(j=0; j<NB_eNB_INST; j++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB_mac_inst[j][CC_id].sbmap_conf.first_subframe=0;
eNB_mac_inst[j][CC_id].sbmap_conf.periodicity=10;
eNB_mac_inst[j][CC_id].sbmap_conf.sb_size=SB_size;
eNB_mac_inst[j][CC_id].sbmap_conf.nb_active_sb=1;
for(i=0;i<NUMBER_OF_SUBBANDS;i++)
for(i=0; i<NUMBER_OF_SUBBANDS; i++) {
eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[i]=1;
}
eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[rand()%NUMBER_OF_SUBBANDS]=0;
}
}
#endif
//end ALU's algo
@@ -328,23 +355,25 @@ int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ui
}
int mac_init_global_param(void){
int mac_init_global_param(void)
{
Mac_rlc_xface = NULL;
LOG_I(MAC,"[MAIN] CALLING RLC_MODULE_INIT...\n");
if (rlc_module_init()!=0)
if (rlc_module_init()!=0) {
return(-1);
}
LOG_I(MAC,"[MAIN] RLC_MODULE_INIT OK, malloc16 for mac_rlc_xface...\n");
Mac_rlc_xface = (MAC_RLC_XFACE*)malloc16(sizeof(MAC_RLC_XFACE));
bzero(Mac_rlc_xface,sizeof(MAC_RLC_XFACE));
if(Mac_rlc_xface == NULL){
LOG_E(MAC,"[MAIN] FATAL EROOR: Could not allocate memory for Mac_rlc_xface !!!\n");
return (-1);
if(Mac_rlc_xface == NULL) {
LOG_E(MAC,"[MAIN] FATAL EROOR: Could not allocate memory for Mac_rlc_xface !!!\n");
return (-1);
}
@@ -389,19 +418,26 @@ int mac_init_global_param(void){
}
void mac_top_cleanup(void){
void mac_top_cleanup(void)
{
#ifndef USER_MODE
pdcp_module_cleanup ();
#endif
if (NB_UE_INST>0)
if (NB_UE_INST>0) {
free (UE_mac_inst);
if (NB_eNB_INST>0)
}
if (NB_eNB_INST>0) {
free(eNB_mac_inst);
}
free( Mac_rlc_xface);
}
int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active) {
int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active)
{
@@ -432,7 +468,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
mac_xface->get_transmission_mode = get_transmission_mode;
mac_xface->get_rballoc = get_rballoc;
mac_xface->get_nb_rb = conv_nprb;
// mac_xface->get_SB_size = Get_SB_size;
// mac_xface->get_SB_size = Get_SB_size;
mac_xface->get_subframe_direction = get_subframe_direction;
mac_xface->Msg3_transmitted = Msg3_tx;
mac_xface->Msg1_transmitted = Msg1_tx;
@@ -486,10 +522,10 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
#endif
#ifdef CBA
mac_xface->phy_config_cba_rnti = phy_config_cba_rnti ;
#endif
#endif
mac_xface->estimate_ue_tx_power = estimate_ue_tx_power;
mac_xface->phy_config_meas_ue = phy_config_meas_ue;
mac_xface->phy_reset_ue = phy_reset_ue;
mac_xface->phy_reset_ue = phy_reset_ue;
mac_xface->phy_config_dedicated_eNB = phy_config_dedicated_eNB;
mac_xface->phy_config_dedicated_ue = phy_config_dedicated_ue;
@@ -498,13 +534,17 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
mac_xface->get_mu_mimo_mode = get_mu_mimo_mode;
mac_xface->get_hundred_times_delta_TF = get_hundred_times_delta_IF_mac;
mac_xface->get_target_ul_rx_power = get_target_ul_rx_power;
mac_xface->get_target_pusch_rx_power = get_target_pusch_rx_power;
mac_xface->get_target_pucch_rx_power = get_target_pucch_rx_power;
mac_xface->get_prach_prb_offset = get_prach_prb_offset;
mac_xface->is_prach_subframe = is_prach_subframe;
#ifdef Rel10
mac_xface->get_mch_sdu = get_mch_sdu;
mac_xface->phy_config_dedicated_scell_eNB= phy_config_dedicated_scell_eNB;
mac_xface->phy_config_dedicated_scell_ue= phy_config_dedicated_scell_ue;
#endif
mac_xface->get_PHR = get_PHR;
+241 -218
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -84,74 +84,80 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
unsigned int stat_timer_poll_retransmit_timed_out;
unsigned int stat_timer_status_prohibit_timed_out;
// UE part
for (ue_id=0;ue_id<NUM_UE_INST;ue_id++){
// UE part
for (ue_id=0; ue_id<NUM_UE_INST; ue_id++) {
// mod_id used for PDCP and RLC
Mod_id = NB_eNB_INST + ue_id ;
Mod_id = NB_eNB_INST + ue_id ;
len+=sprintf(&buffer[len],"UE TTI: %d\n",UE_mac_inst[ue_id].frame);
len+=sprintf(&buffer[len],"UE TTI: %d\n",UE_mac_inst[ue_id].frame);
for (enb_id= 0; enb_id <NB_SIG_CNX_UE;enb_id++) {
switch (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
case RRC_RECONFIGURED :
case RRC_CONNECTED:
case RRC_SI_RECEIVED:
case RRC_IDLE:
break;
if (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
// if (UE_mac_inst[ue_id].Dcch_lchan[CH_index].Active==1) {
len+=sprintf(&buffer[len],"eNB %d: Wideband SINR %d dB---\n",
CH_index,UE_mac_inst[Mod_id].Def_meas[CH_index].Wideband_sinr);
len+=sprintf(&buffer[len],"CH %d: Subband SINR (dB) :",
CH_index);
for (fg=0;fg<NUMBER_OF_MEASUREMENT_SUBBANDS;fg++)
len+=sprintf(&buffer[len],"%d ",UE_mac_inst[Mod_id].Def_meas[CH_index].Sinr_meas[0][fg]);
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len],"BCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"CCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"LCHAN %d (DCCH), NB_TX_MAC = %d (%d bits/TTI, %d kbits/sec), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
for(i=1;i<NB_RAB_MAX;i++){
if (UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Active==1) {
Overhead=UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][CH_index][i];
if(Overhead<0){
Overhead=-Overhead;
Sign=-1;
}
else Sign=1;
len+=sprintf(&buffer[len],"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s) , LAYER2 TX OVERHEAD: %d Kbits/s\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][CH_index][i],
Pdcp_stats_tx_rate[k][CH_index][i],
(10*Pdcp_stats_tx_rate[k][CH_index][i])>>5,
Pdcp_stats_rx[k][CH_index][i],
Pdcp_stats_rx_rate[k][CH_index][i],
(10*Pdcp_stats_rx_rate[k][CH_index][i])>>5,
Sign*(10*Overhead)>>5);
for (enb_id= 0; enb_id <NB_SIG_CNX_UE; enb_id++) {
switch (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
case RRC_RECONFIGURED :
case RRC_CONNECTED:
case RRC_SI_RECEIVED:
case RRC_IDLE:
break;
if (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
// if (UE_mac_inst[ue_id].Dcch_lchan[CH_index].Active==1) {
len+=sprintf(&buffer[len],"eNB %d: Wideband SINR %d dB---\n",
CH_index,UE_mac_inst[Mod_id].Def_meas[CH_index].Wideband_sinr);
len+=sprintf(&buffer[len],"CH %d: Subband SINR (dB) :",
CH_index);
for (fg=0; fg<NUMBER_OF_MEASUREMENT_SUBBANDS; fg++) {
len+=sprintf(&buffer[len],"%d ",UE_mac_inst[Mod_id].Def_meas[CH_index].Sinr_meas[0][fg]);
}
len+=sprintf(&buffer[len],"\n");
int status = rlc_stat_req (k,
len+=sprintf(&buffer[len],"BCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"CCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"LCHAN %d (DCCH), NB_TX_MAC = %d (%d bits/TTI, %d kbits/sec), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
for(i=1; i<NB_RAB_MAX; i++) {
if (UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Active==1) {
Overhead=UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][CH_index][i];
if(Overhead<0) {
Overhead=-Overhead;
Sign=-1;
} else {
Sign=1;
}
len+=sprintf(&buffer[len],"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s) , LAYER2 TX OVERHEAD: %d Kbits/s\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][CH_index][i],
Pdcp_stats_tx_rate[k][CH_index][i],
(10*Pdcp_stats_tx_rate[k][CH_index][i])>>5,
Pdcp_stats_rx[k][CH_index][i],
Pdcp_stats_rx_rate[k][CH_index][i],
(10*Pdcp_stats_rx_rate[k][CH_index][i])>>5,
Sign*(10*Overhead)>>5);
int status = rlc_stat_req (k,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
&stat_tx_pdcp_sdu,
&stat_tx_pdcp_bytes,
@@ -180,171 +186,185 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
&stat_timer_reordering_timed_out,
&stat_timer_poll_retransmit_timed_out,
&stat_timer_status_prohibit_timed_out) ;
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %d",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d/%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS_TB[kk],
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %d",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) {
len+=sprintf(&buffer[len],"%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX_TB[kk]);
}
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++)
len+=sprintf(&buffer[len],"%d/%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS_TB[kk],
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
}
}
}
}
}
}
}
#endif //PHY_EMUL_ONE_MACHINE
}
else if(Mac_rlc_xface->Is_cluster_head[k] ==1){
else if(Mac_rlc_xface->Is_cluster_head[k] ==1) {
Mod_id=k;
len+=sprintf(&buffer[len],"-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n",
NODE_ID[Mod_id],Mac_rlc_xface->frame);
Mod_id=k;
len+=sprintf(&buffer[len],
"-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n",
NODE_ID[Mod_id],Mac_rlc_xface->frame);
for(i=1;i<=NB_CNX_CH;i++){
if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) {
len+=sprintf(&buffer[len],"\nMR index %d: DL SINR (feedback) %d dB, CQI: %s\n\n",
i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0],
CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr);
//print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi));
for(i=1; i<=NB_CNX_CH; i++) {
if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) {
len+=sprintf(&buffer[len],"\nMR index %d: DL SINR (feedback) %d dB, CQI: %s\n\n",
i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0],
CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr);
//print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi));
len+=sprintf(&buffer[len],"[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n",
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING);
for(j=0;j<NB_RAB_MAX;j++){
if (CH_mac_inst[Mod_id].Dtch_lchan[j][i].Active==1){
Overhead=CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][i][j];
if(Overhead<0){
Overhead=-Overhead;
Sign=-1;
}
else Sign=1;
len+=sprintf(&buffer[len],"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s), LAYER2 TX OVERHEAD= %d Kbits/s\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][i][j],
Pdcp_stats_tx_rate[k][i][j],
(10*Pdcp_stats_tx_rate[k][i][j])>>5,
Pdcp_stats_rx[k][i][j],
Pdcp_stats_rx_rate[k][i][j],
(10*Pdcp_stats_rx_rate[k][i][j])>>5,
Sign*(10*Overhead)>>5);
int status = rlc_stat_req (k,
len+=sprintf(&buffer[len],
"[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n",
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING);
for(j=0; j<NB_RAB_MAX; j++) {
if (CH_mac_inst[Mod_id].Dtch_lchan[j][i].Active==1) {
Overhead=CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][i][j];
if(Overhead<0) {
Overhead=-Overhead;
Sign=-1;
} else {
Sign=1;
}
len+=sprintf(&buffer[len],
"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s), LAYER2 TX OVERHEAD= %d Kbits/s\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][i][j],
Pdcp_stats_tx_rate[k][i][j],
(10*Pdcp_stats_tx_rate[k][i][j])>>5,
Pdcp_stats_rx[k][i][j],
Pdcp_stats_rx_rate[k][i][j],
(10*Pdcp_stats_rx_rate[k][i][j])>>5,
Sign*(10*Overhead)>>5);
int status = rlc_stat_req (k,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
&tx_pdcp_sdu,
&tx_pdcp_sdu_discarded,
&tx_retransmit_pdu_unblock,
&tx_retransmit_pdu_by_status,
&tx_retransmit_pdu,
&tx_data_pdu,
&tx_control_pdu,
&rx_sdu,
&rx_error_pdu,
&rx_data_pdu,
&rx_data_pdu_out_of_window,
&rx_control_pdu) ;
/*
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
*/
len+=sprintf(&buffer[len],"[MAC]LCHAN %d (CNX %d,RAB %d), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
i,j,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING);
len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX);
&tx_pdcp_sdu,
&tx_pdcp_sdu_discarded,
&tx_retransmit_pdu_unblock,
&tx_retransmit_pdu_by_status,
&tx_retransmit_pdu,
&tx_data_pdu,
&tx_control_pdu,
&rx_sdu,
&rx_error_pdu,
&rx_data_pdu,
&rx_data_pdu_out_of_window,
&rx_control_pdu) ;
/*
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
*/
len+=sprintf(&buffer[len],
"[MAC]LCHAN %d (CNX %d,RAB %d), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
i,j,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING);
len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX);
/*
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d.",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d/%d . ",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS_TB[kk],
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
*/
}
}
}
/*
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d.",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d/%d . ",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS_TB[kk],
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
*/
}
}
}
}
}
}
return len;
return len;
}
#ifndef USER_MODE
@@ -362,12 +382,15 @@ int add_openair2_stats()
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
// pde = proc_create_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root);
pde = create_proc_read_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, (read_proc_t*)&openair2_stats_read, NULL);
if (!pde)
if (!pde) {
printk("[OPENAIR][ERROR] can't create proc entry !\n");
//#else
}
//#else
//create_proc_info_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, openair2_stats_read);
//#endif
//#endif
return 0;
}
/*
@@ -379,8 +402,8 @@ void remove_openair2_stats()
if (proc_openair2_root) {
printk("[OPENAIR][CLEANUP] Removing openair proc entry\n");
remove_proc_entry("lchan_stats", proc_openair2_root);
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
//#else
remove_proc_entry("openair2",NULL);
//#endif;
File diff suppressed because it is too large Load Diff
+130 -114
View File
@@ -21,29 +21,34 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file proto.h
/*! \file LAYER2/MAC/proto.h
* \brief MAC functions prototypes for eNB and UE
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \date 2010 - 2014
* \email navid.nikaein@eurecom.fr
* \version 1.0
* @ingroup _mac
*/
#ifndef __LAYER2_MAC_PROTO_H__
#define __LAYER2_MAC_PROTO_H__
/** \addtogroup _mac
* @{
*/
/** \fn void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag);
\brief
*/
void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag);
//LG commented cause compilation error for RT eNB extern inline unsigned int taus(void);
/** \brief First stage of Random-Access Scheduling. Loops over the RA_templates and checks if RAR, Msg3 or its retransmission are to be scheduled in the subframe. It returns the total number of PRB used for RA SDUs. For Msg3 it retrieves the L3msg from RRC and fills the appropriate buffers. For the others it just computes the number of PRBs. Each DCI uses 3 PRBs (format 1A)
/** \fn void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,unsigned int *nprb,unsigned int *nCCE);
\brief First stage of Random-Access Scheduling. Loops over the RA_templates and checks if RAR, Msg3 or its retransmission are to be scheduled in the subframe. It returns the total number of PRB used for RA SDUs. For Msg3 it retrieves the L3msg from RRC and fills the appropriate buffers. For the others it just computes the number of PRBs. Each DCI uses 3 PRBs (format 1A)
for the message.
@param Mod_id Instance ID of eNB
@param frame Frame index
@@ -73,7 +78,7 @@ int schedule_MBMS(module_id_t module_idP,uint8_t CC_id, frame_t frameP, sub_fram
/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping
@param Mod_id Instance ID of eNB
@param mbsfn_sync_area index of mbsfn sync area
@param[out] index of sf pattern
@param[out] index of sf pattern
*/
int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area);
@@ -81,7 +86,7 @@ int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mb
@param Mod_id Instance ID of eNB
@param mbsfn_sync_area index of mbsfn sync area
@param eNB_index index of eNB
@param[out] index of sf pattern
@param[out] index of sf pattern
*/
int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index);
@@ -94,25 +99,27 @@ int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_are
*/
void schedule_ulsch(module_id_t module_idP,frame_t frameP,unsigned char cooperation_flag,sub_frame_t subframe,unsigned char sched_subframe,unsigned int *nCCE);
/** \brief ULSCH Scheduling per RNTI
/** \brief ULSCH Scheduling per RNTI
@param Mod_id Instance ID of 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)
@param nCCE Pointer to current nCCE count
*/
void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb);
void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE, unsigned int *nCCE_available,
uint16_t *first_rb);
/** \brief ULSCH Scheduling for CBA RNTI
/** \brief ULSCH Scheduling for CBA RNTI
@param Mod_id Instance ID of 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)
@param nCCE Pointer to current nCCE count
*/
void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb);
void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE,
unsigned int *nCCE_available, uint16_t *first_rb);
/** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4.
/** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4.
@param Mod_id Instance of eNB
@param frame Frame index
@param subframe Index of subframe
@@ -122,7 +129,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
*/
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint32_t *rballoc,uint8_t RA_scheduled,int *mbsfn_flag);
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe on which to act
@@ -138,14 +145,15 @@ void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe
*/
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id);
/** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
/** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@returns DELTA_PREAMBLE
*/
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id);
/** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
/** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@param CC_id carrier component id of UE
@returns deltaP_rampup
*/
int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id);
@@ -170,55 +178,45 @@ void mac_top_cleanup(void);
void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_index);
void dlsch_scheduler_pre_processor_reset (int UE_id,
uint8_t CC_id,
int N_RBG,
uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
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[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][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 frame Index of frame
@param subframe Index of current subframe
@param dl_pow_off Pointer to store resulting power offset for DCI
@param pre_nb_available_rbs Pointer to store number of remaining rbs after scheduling
@param N_RBS Number of resource block groups
@param rb_alloc_sub Table of resource block groups allocated to each UE
*/
void dlsch_scheduler_pre_processor (module_id_t module_idP,
frame_t frameP,
sub_frame_t subframe,
uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int N_RBG[MAX_NUM_CCs],
unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
int *mbsfn_flag);
int *mbsfn_flag);
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,
uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
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[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][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
/* \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. The resultant DCI_PDU is
ready after returning from this call.
@param Mod_id Instance ID of eNB
@@ -241,7 +239,7 @@ DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request
@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
*/
void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id);
@@ -251,12 +249,14 @@ void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t
@param N_RB_UL Number of UL resource blocks
@returns t_CRNTI
*/
uint16_t fill_rar(module_id_t module_idP,
int CC_id,
frame_t frameP,
uint8_t *dlsch_buffer,
uint16_t N_RB_UL,
uint8_t input_buffer_length);
unsigned short fill_rar(
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
uint8_t * const dlsch_buffer,
const uint16_t N_RB_UL,
const uint8_t input_buffer_length
);
/* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE
@param Mod_id Instance ID of eNB
@@ -271,7 +271,7 @@ void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t pr
@param harq_pid Index of harq process corresponding to this sdu
@param msg3_flag flag indicating that this sdu is msg3
*/
void rx_sdu(module_id_t module_idP, int CC_id,frame_t frameP, rnti_t rnti, uint8_t *sdu, uint16_t sdu_len, int harq_pid,uint8_t *msg3_flag);
void rx_sdu(const module_id_t module_idP, const int CC_id,const frame_t frameP, const sub_frame_t subframeP, const rnti_t rnti, uint8_t *sdu, const uint16_t sdu_len, const int harq_pid,uint8_t *msg3_flag);
/* \brief Function to indicate a scheduled schduling request (SR) was received by eNB.
@param Mod_id Instance ID of eNB
@@ -286,10 +286,10 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn
@param Mod_id Instance ID of eNB
@param frame Index of frame
@param subframe Index of current subframe
@param mcs Pointer to mcs used by PHY (to be filled by MAC)
@param mcs Pointer to mcs used by PHY (to be filled by MAC)
@returns Pointer to MCH transport block and mcs for subframe
*/
MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint8_t CC_id, uint32_t frame,sub_frame_t subframe);
MCH_PDU *get_mch_sdu( module_id_t Mod_id, int CC_id, frame_t frame, sub_frame_t subframe);
//added for ALU icic purpose
@@ -313,10 +313,10 @@ uint8_t process_ue_cqi (module_id_t module_idP, int UE_id);
int8_t find_active_UEs_with_traffic(module_id_t module_idP);
void set_ue_dai(sub_frame_t subframeP,
uint8_t tdd_config,
int UE_id,
uint8_t CC_id,
UE_list_t *UE_list);
uint8_t tdd_config,
int UE_id,
uint8_t CC_id,
UE_list_t *UE_list);
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id);
@@ -343,7 +343,7 @@ int schedule_next_dlue(module_id_t module_idP, int CC_id, sub_frame_t subframe);
uint32_t allocate_prbs(int UE_id,uint8_t nb_rb, uint32_t *rballoc);
/* \fn uint32_t req_new_ulsch(module_id_t module_idP)
\brief check for a new transmission in any drb
\brief check for a new transmission in any drb
@param Mod_id Instance id of UE in machine
@returns 1 for new transmission, 0 for none
*/
@@ -393,7 +393,7 @@ int ue_query_mch(uint8_t Mod_id,uint8_t CC_id, uint32_t frame,sub_frame_t subfra
#endif
/* \brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
/* \brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
@param Mod_id Instance id of UE in machine
@param eNB_id Index of eNB that UE is attached to
@param rnti C_RNTI of UE
@@ -414,15 +414,23 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,u
@param Mod_id Index of UE instance
@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
@param t_crnti Pointer to PHY variable containing the T_CRNTI
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
random-access procedure
@returns timing advance or 0xffff if preamble doesn't match
*/
uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index);
uint16_t
ue_process_rar(
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
uint8_t * const dlsch_buffer,
rnti_t * const t_crnti,
const uint8_t preamble_index
);
/* \brief Generate header for UL-SCH. This function parses the desired control elements and sdus and generates the header as described
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in the ULSCH buffer.
@param mac_header Pointer to the first byte of the MAC header (UL-SCH buffer)
@param num_sdus Number of SDUs in the payload
@@ -450,7 +458,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
unsigned short post_padding);
/* \brief Parse header for UL-SCH. This function parses the received UL-SCH header as described
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in the ULSCH buffer.
@param mac_header Pointer to the first byte of the MAC header (UL-SCH buffer)
@param num_ces Number of SDUs in the payload
@@ -461,18 +469,18 @@ in the ULSCH buffer.
@returns Pointer to payload following header
*/
uint8_t *parse_ulsch_header(uint8_t *mac_header,
uint8_t *num_ce,
uint8_t *num_sdu,
uint8_t *rx_ces,
uint8_t *rx_lcids,
uint16_t *rx_lengths,
uint16_t tx_lenght);
uint8_t *num_ce,
uint8_t *num_sdu,
uint8_t *rx_ces,
uint8_t *rx_lcids,
uint16_t *rx_lengths,
uint16_t tx_lenght);
int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
int mac_init(void);
int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti,int harq_pid);
int mac_remove_ue(module_id_t Mod_id, int UE_id,int frameP);
int mac_remove_ue(module_id_t Mod_id, int UE_id,int frameP, sub_frame_t subframeP);
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag);
@@ -490,15 +498,21 @@ 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 frameP, sub_frame_t subframeP,uint16_t *first_rb);
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE *UE_template);
/*! \fn UE_L2_state_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t subframe, lte_subframe_t direction,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.
/*! \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.
\param[in] module_idP instance of the UE
\param[in] subframe t the subframe number
\param[in] direction subframe direction
\param[in] eNB_index instance of eNB
@returns L2 state (CONNETION_OK or CONNECTION_LOST or PHY_RESYNCH)
*/
UE_L2_STATE_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t subframe, lte_subframe_t direction,uint8_t eNB_index,int CC_id);
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,
const int CC_id);
/*! \fn int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen);
\brief determine whether to use cba resource to transmit or not
@@ -506,7 +520,7 @@ UE_L2_STATE_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t su
\param[in] frame the frame number
\param[in] subframe the subframe number
\param[in] eNB_index instance of eNB
\param[out] access(1) or postpone (0)
\param[out] access(1) or postpone (0)
*/
int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen);
@@ -518,10 +532,10 @@ int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8
int get_bsr_lcgid (module_id_t module_idP);
/*! \fn uint8_t get_bsr_len (module_id_t module_idP,uint16_t bufflen);
\brief determine whether the bsr is short or long assuming that the MAC pdu is built
\brief determine whether the bsr is short or long assuming that the MAC pdu is built
\param[in] Mod_id instance of the UE
\param[in] bufflen size of phy transport block
\param[out] bsr_len size of bsr control element
\param[out] bsr_len size of bsr control element
*/
uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen);
@@ -542,18 +556,18 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len);
BSR_LONG * get_bsr_long(module_id_t module_idP, uint8_t bsr_len);
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid)
\brief get the rlc stats and update the bsr level for each lcid
\brief get the rlc stats and update the bsr level for each lcid
\param[in] Mod_id instance of the UE
\param[in] frame Frame index
\param[in] lcid logical channel identifier
*/
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid, uint8_t lcgid);
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, eNB_index_t eNB_index, uint8_t lcid, uint8_t lcgid);
/*! \fn locate (int *table, int size, int value)
\brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
\brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
\param[in] *table Pointer to BSR table
\param[in] size Size of the table
\param[in] value Value of the buffer
\param[in] value Value of the buffer
\return the index in the BSR_LEVEL table
*/
uint8_t locate (const uint32_t *table, int size, int value);
@@ -642,13 +656,13 @@ double uniform_rngen(int min, int max);
void add_common_dci(DCI_PDU *DCI_pdu,
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t ra_flag);
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t ra_flag);
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc);
@@ -657,39 +671,40 @@ void update_ul_dci(module_id_t module_idP,uint8_t CC_id,rnti_t rnti,uint8_t dai)
int get_min_rb_unit(module_id_t module_idP, uint8_t CC_id);
/* \brief Generate header for DL-SCH. This function parses the desired control elements and sdus and generates the header as described
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
in the DLSCH buffer.
@param mac_header Pointer to the first byte of the MAC header (DL-SCH buffer)
@param num_sdus Number of SDUs in the payload
@param sdu_lengths Pointer to array of SDU lengths
@param sdu_lcids Pointer to array of LCIDs (the order must be the same as the SDU length array)
@param drx_cmd dicontinous reception command
@param drx_cmd dicontinous reception command
@param timing_advancd_cmd timing advanced command
@param ue_cont_res_id Pointer to contention resolution identifier (NULL means not present in payload)
@param short_padding Number of bytes for short padding (0,1,2)
@param post_padding number of bytes for padding at the end of MAC PDU
@param post_padding number of bytes for padding at the end of MAC PDU
@returns Number of bytes used for header
*/
unsigned char generate_dlsch_header(unsigned char *mac_header,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char drx_cmd,
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,
short timing_advance_cmd,
unsigned char *ue_cont_res_id,
unsigned char short_padding,
unsigned short post_padding);
/** \brief RRC Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
@param Mod_id Instance ID of eNB
@param CC_id Component Carrier of the eNB
@param eNB_flag Indicates if this is a eNB or UE configuration
@param UE_id Index of UE if this is an eNB configuration
@param rntiP id of UE if this is an eNB configuration
@param eNB_id Index of eNB if this is a UE configuration
@param radioResourceConfigCommon Structure from SIB2 for common radio parameters (if NULL keep existing configuration)
@param physcialConfigDedicated Structure from RRCConnectionSetup or RRCConnectionReconfiguration for dedicated PHY parameters (if NULL keep existing configuration)
@param measObj Structure from RRCConnectionReconfiguration for UE measurement procedures
@param mac_MainConfig Structure from RRCConnectionSetup or RRCConnectionReconfiguration for dedicated MAC parameters (if NULL keep existing configuration)
@param logicalChannelIdentity Logical channel identity index of corresponding logical channel config
@param logicalChannelIdentity Logical channel identity index of corresponding logical channel config
@param logicalChannelConfig Pointer to logical channel configuration
@param measGapConfig Measurement Gap configuration for MAC (if NULL keep existing configuration)
@param tdd_Config TDD Configuration from SIB1 (if NULL keep existing configuration)
@@ -702,14 +717,15 @@ unsigned char generate_dlsch_header(unsigned char *mac_header,
@param pmch_InfoList pointer to PMCH_InfoList from MBSFNAreaConfiguration Message (MCCH Message)
*/
int rrc_mac_config_req(module_id_t module_idP,
int CC_id,
eNB_flag_t eNB_flag,
uint8_t UE_id,
rnti_t rntiP,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
@@ -736,7 +752,7 @@ int rrc_mac_config_req(module_id_t module_idP,
uint8_t num_active_cba_groups,
uint16_t cba_rnti
#endif
);
);
/** \brief get the estimated UE distance from the PHY->MAC layer.
@param Mod_id Instance ID of eNB
@@ -745,12 +761,12 @@ int rrc_mac_config_req(module_id_t module_idP,
@param loc_type localization type: time-based or power-based
@return the estimated distance in meters
*/
double
rrc_get_estimated_ue_distance(module_id_t Mod_id,
const frame_t frameP,
uint8_t UE_id,
int CC_id,
uint8_t loc_type);
double
rrc_get_estimated_ue_distance(
const protocol_ctxt_t * const ctxt_pP,
const int CC_idP,
const uint8_t loc_typeP);
#endif
/** @}*/
+369 -250
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -55,9 +55,10 @@
#include "SIMULATION/simulation_defs.h"
#endif
extern inline unsigned int taus(void);
#include "SIMULATION/TOOLS/defs.h" // for taus
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) {
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id)
{
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
@@ -69,139 +70,199 @@ int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) {
uint8_t preambleformat;
if (UE_mac_inst[module_idP].tdd_Config) { // TDD
if (prachConfigIndex < 20)
preambleformat = 0;
else if (prachConfigIndex < 30)
preambleformat = 1;
else if (prachConfigIndex < 40)
preambleformat = 2;
else if (prachConfigIndex < 48)
preambleformat = 3;
else
preambleformat = 4;
}
else { // FDD
preambleformat = prachConfigIndex>>2;
if (prachConfigIndex < 20) {
preambleformat = 0;
} else if (prachConfigIndex < 30) {
preambleformat = 1;
} else if (prachConfigIndex < 40) {
preambleformat = 2;
} else if (prachConfigIndex < 48) {
preambleformat = 3;
} else {
preambleformat = 4;
}
} else { // FDD
preambleformat = prachConfigIndex>>2;
}
switch (preambleformat) {
case 0:
case 1:
return(0);
case 2:
case 3:
return(-3);
case 4:
return(8);
default:
LOG_E(MAC,"[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n",
module_idP,
preambleformat,prachConfigIndex);
module_idP,
preambleformat,prachConfigIndex);
mac_xface->macphy_exit("MAC get_DELTA_PREAMBLE Illegal preamble format");
return(0);
}
}
/// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321
void get_prach_resources(module_id_t module_idP,
int CC_id,
uint8_t eNB_index,
uint8_t t_id,
uint8_t first_Msg3,
RACH_ConfigDedicated_t *rach_ConfigDedicated) {
int CC_id,
uint8_t eNB_index,
uint8_t t_id,
uint8_t first_Msg3,
RACH_ConfigDedicated_t *rach_ConfigDedicated)
{
uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size;
PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources;
RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
uint8_t noGroupB = 0;
uint8_t f_id = 0,num_prach=0;
int numberOfRA_Preambles;
int messageSizeGroupA;
int sizeOfRA_PreamblesGroupA;
int messagePowerOffsetGroupB;
int PLThreshold;
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else {
LOG_E(MAC,"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP);
mac_xface->macphy_exit("MAC FATAL radioResourceConfigCommon is NULL");
return; // not reached
} else {
LOG_E(MAC,"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP);
mac_xface->macphy_exit("MAC FATAL radioResourceConfigCommon is NULL");
return; // not reached
}
numberOfRA_Preambles = (1+rach_ConfigCommon->preambleInfo.numberOfRA_Preambles)<<2;
if (rach_ConfigDedicated) { // This is for network controlled Mobility, later
if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) {
prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
prach_resources->ra_RACH_MaskIndex = rach_ConfigDedicated->ra_PRACH_MaskIndex;
return;
}
if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) {
prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
prach_resources->ra_RACH_MaskIndex = rach_ConfigDedicated->ra_PRACH_MaskIndex;
return;
}
}
if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
noGroupB = 1;
noGroupB = 1;
} else {
sizeOfRA_PreamblesGroupA = (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA+1)<<2;
switch (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messageSizeGroupA) {
case 0:
messageSizeGroupA = 56;
break;
case 1:
messageSizeGroupA = 144;
break;
case 2:
messageSizeGroupA = 208;
break;
case 3:
messageSizeGroupA = 256;
break;
}
}
else {
if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA ==
rach_ConfigCommon->preambleInfo.numberOfRA_Preambles)
noGroupB = 1;
switch (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB) {
case 0:
messagePowerOffsetGroupB = -9999;
break;
case 1:
messagePowerOffsetGroupB = 0;
break;
case 2:
messagePowerOffsetGroupB = 5;
break;
case 3:
messagePowerOffsetGroupB = 8;
break;
case 4:
messagePowerOffsetGroupB = 10;
break;
case 5:
messagePowerOffsetGroupB = 12;
break;
case 6:
messagePowerOffsetGroupB = 15;
break;
case 7:
messagePowerOffsetGroupB = 18;
break;
}
PLThreshold = 0 - get_DELTA_PREAMBLE(module_idP,CC_id) - get_Po_NOMINAL_PUSCH(module_idP,CC_id) - messagePowerOffsetGroupB;
// Note Pcmax is set to 0 here, we have to fix this
if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) {
noGroupB = 1;
}
}
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())&0x3f;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
if (noGroupB == 1) {
// use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%numberOfRA_Preambles;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else if ((Msg3_size <messageSizeGroupA) ||
(mac_xface->get_PL(module_idP,0,eNB_index) > PLThreshold)) {
// use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%sizeOfRA_PreamblesGroupA;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else { // use Group B
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = sizeOfRA_PreamblesGroupA +
(taus())%(numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 0;
}
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
} else { // Msg3 is being retransmitted
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
} else {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())&0x3f;
}
else if ((Msg3_size < rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messageSizeGroupA) ||
(mac_xface->get_PL(module_idP,0,eNB_index) > UE_mac_inst[module_idP].RA_maxPL)) {
// use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
}
else { // use Group B
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
(taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
} else {
// FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
(taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 0;
}
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
}
else { // Msg3 is being retransmitted
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig)
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
else
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())&0x3f;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
}
else {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
(taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
}
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
}
}
// choose random PRACH resource in TDD
if (UE_mac_inst[module_idP].tdd_Config) {
num_prach = mac_xface->get_num_prach_tdd(mac_xface->lte_frame_parms);
if ((num_prach>0) && (num_prach<6))
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = (taus()%num_prach);
f_id = mac_xface->get_fid_prach_tdd(mac_xface->lte_frame_parms,
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index);
num_prach = mac_xface->get_num_prach_tdd(mac_xface->lte_frame_parms);
if ((num_prach>0) && (num_prach<6)) {
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = (taus()%num_prach);
}
f_id = mac_xface->get_fid_prach_tdd(mac_xface->lte_frame_parms,
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index);
}
// choose RA-RNTI
UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id;
}
void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) {
void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id)
{
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
@@ -211,18 +272,19 @@ void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id
// start contention resolution timer
UE_mac_inst[module_idP].RA_attempt_number++;
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled) {
trace_pdu(0, NULL, 0, module_idP, 3, UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex,
UE_mac_inst[module_idP].subframe, 0, UE_mac_inst[module_idP].RA_attempt_number);
LOG_D(OPT,"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n",
if (opt_enabled) {
trace_pdu(0, NULL, 0, module_idP, 2, UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex,
UE_mac_inst[module_idP].subframe, 0, UE_mac_inst[module_idP].RA_attempt_number);
LOG_D(OPT,"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size);
}
#endif
}
void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) {
void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id)
{
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
@@ -231,22 +293,22 @@ void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id
}
// start contention resolution timer
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP);
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP);
UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0;
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1;
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.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, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].subframe, 0, 0);
LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n",
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, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].subframe, 0, 0);
LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n",
module_idP, frameP, UE_mac_inst[module_idP].crnti /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex*/, UE_mac_inst[module_idP].RA_Msg3_size);
}
#endif
}
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP)
{
uint8_t Size=0;
@@ -267,172 +329,229 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
}
if (UE_mode == PRACH) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else {
return(NULL);
}
if (Is_rrc_registered == 1) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
} else {
return(NULL);
}
if (UE_mac_inst[module_idP].RA_active == 0) {
printf("RA not active\n");
// check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP,
frameP,
CCCH,1,
&UE_mac_inst[module_idP].CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT)+1],0,
eNB_indexP,
0);
Size16 = (uint16_t)Size;
if (Is_rrc_registered == 1) {
// LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n",
frameP, module_idP, eNB_indexP, module_idP);
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
if (UE_mac_inst[module_idP].RA_active == 0) {
LOG_D(MAC,"RA not active\n");
// check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP,
CC_id,
frameP,
CCCH,1,
&UE_mac_inst[module_idP].CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT)+1],0,
eNB_indexP,
0);
Size16 = (uint16_t)Size;
if (Size>0) {
// LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n",
frameP, module_idP, eNB_indexP, module_idP);
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].RA_Msg3_size = Size+sizeof(SCH_SUBHEADER_SHORT)+sizeof(SCH_SUBHEADER_SHORT);
UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = UE_mac_inst[module_idP].CCCH_pdu.payload;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
if (rach_ConfigCommon) {
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
if (UE_mac_inst[module_idP].RA_window_cnt == 9)
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
else {
LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
}
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
if (Size>0) {
generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
1); //post_padding
UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].RA_Msg3_size = Size+sizeof(SCH_SUBHEADER_SHORT)+sizeof(SCH_SUBHEADER_SHORT);
UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = UE_mac_inst[module_idP].CCCH_pdu.payload;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DCCH] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
rlc_status = mac_rlc_status_ind(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
DCCH,
6);
if (UE_mac_inst[module_idP].crnti_before_ho)
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
module_idP,frameP, UE_mac_inst[module_idP].crnti,UE_mac_inst[module_idP].crnti_before_ho, rlc_status.bytes_in_buffer,dcch_header_len);
else
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
module_idP,frameP, rlc_status.bytes_in_buffer,dcch_header_len);
if (rach_ConfigCommon) {
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
sdu_lengths[0] = mac_rlc_data_req(eNB_indexP, module_idP,frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
DCCH,
(char *)&ulsch_buff[0]);
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
update_bsr(module_idP, frameP, DCCH,UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
//header_len +=2;
UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].RA_Msg3_size = Size+dcch_header_len;
UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = ulsch_buff;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
if (rach_ConfigCommon) {
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
if (UE_mac_inst[module_idP].RA_window_cnt == 9)
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
else {
LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
}
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
generate_ulsch_header((uint8_t*)ulsch_buff, // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
&UE_mac_inst[module_idP].crnti, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
} else {
LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
}
else { // RACH is active
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",module_idP,
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt,
UE_mac_inst[module_idP].RA_tx_frame,UE_mac_inst[module_idP].RA_tx_subframe);
// compute backoff parameters
if (UE_mac_inst[module_idP].RA_backoff_cnt>0) {
frame_diff = (sframe_t)frameP - UE_mac_inst[module_idP].RA_backoff_frame;
if (frame_diff < 0)
frame_diff = -frame_diff;
UE_mac_inst[module_idP].RA_backoff_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_backoff_subframe));
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
}
// compute RA window parameters
if (UE_mac_inst[module_idP].RA_window_cnt>0) {
frame_diff = (frame_t)frameP - UE_mac_inst[module_idP].RA_tx_frame;
if (frame_diff < 0)
frame_diff = -frame_diff;
UE_mac_inst[module_idP].RA_window_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_tx_subframe));
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",module_idP,
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt);
}
if ((UE_mac_inst[module_idP].RA_window_cnt<=0) &&
(UE_mac_inst[module_idP].RA_backoff_cnt<=0)) {
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1); // 2dB increments in ASN.1 definition
if (UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER == rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) {
LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax);
// send message to RRC
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
}
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0;
generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
1); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources);
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL);
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
} else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DCCH] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
DCCH,
6);
if (UE_mac_inst[module_idP].crnti_before_ho)
LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
module_idP,frameP, UE_mac_inst[module_idP].crnti,UE_mac_inst[module_idP].crnti_before_ho, rlc_status.bytes_in_buffer,dcch_header_len);
else
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
module_idP,frameP, rlc_status.bytes_in_buffer,dcch_header_len);
sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti,
eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
DCCH,
(char *)&ulsch_buff[0]);
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
update_bsr(module_idP, frameP, eNB_indexP,DCCH,UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
//header_len +=2;
UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].RA_Msg3_size = Size+dcch_header_len;
UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = ulsch_buff;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
if (rach_ConfigCommon) {
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
} else {
LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
}
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
generate_ulsch_header((uint8_t*)ulsch_buff, // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
&UE_mac_inst[module_idP].crnti, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
} else { // RACH is active
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",module_idP,
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt,
UE_mac_inst[module_idP].RA_tx_frame,UE_mac_inst[module_idP].RA_tx_subframe);
// compute backoff parameters
if (UE_mac_inst[module_idP].RA_backoff_cnt>0) {
frame_diff = (sframe_t)frameP - UE_mac_inst[module_idP].RA_backoff_frame;
if (frame_diff < 0) {
frame_diff = -frame_diff;
}
UE_mac_inst[module_idP].RA_backoff_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_backoff_subframe));
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
}
// compute RA window parameters
if (UE_mac_inst[module_idP].RA_window_cnt>0) {
frame_diff = (frame_t)frameP - UE_mac_inst[module_idP].RA_tx_frame;
if (frame_diff < 0) {
frame_diff = -frame_diff;
}
UE_mac_inst[module_idP].RA_window_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_tx_subframe));
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",module_idP,
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt);
}
if ((UE_mac_inst[module_idP].RA_window_cnt<=0) &&
(UE_mac_inst[module_idP].RA_backoff_cnt<=0)) {
UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER +=
(rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1); // 2dB increments in ASN.1 definition
int preambleTransMax;
switch (rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) {
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3:
preambleTransMax = 3;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4:
preambleTransMax = 4;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5:
preambleTransMax = 5;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6:
preambleTransMax = 6;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7:
preambleTransMax = 7;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8:
preambleTransMax = 8;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10:
preambleTransMax = 10;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20:
preambleTransMax = 20;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50:
preambleTransMax = 50;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100:
preambleTransMax = 100;
break;
case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200:
preambleTransMax = 200;
break;
}
if (UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) {
LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,preambleTransMax);
// send message to RRC
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
}
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL);
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
}
}
} else if (UE_mode == PUSCH) {
LOG_D(MAC,"[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",module_idP);
mac_xface->macphy_exit("MAC FATAL: Should not have checked for RACH in PUSCH yet");
}
else if (UE_mode == PUSCH) {
LOG_D(MAC,"[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",module_idP);
mac_xface->macphy_exit("MAC FATAL: Should not have checked for RACH in PUSCH yet");
}
return(NULL);
}
+62 -45
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -54,14 +54,17 @@ extern unsigned int distRIV2alloc_LUT25[512];
extern unsigned short RIV2nb_rb_LUT25[512];
extern unsigned short RIV2first_rb_LUT25[512];
extern inline unsigned int taus(void);
unsigned short fill_rar(module_id_t module_idP,
int CC_id,
frame_t frameP,
uint8_t *dlsch_buffer,
uint16_t N_RB_UL,
uint8_t input_buffer_length) {
//------------------------------------------------------------------------------
unsigned short fill_rar(
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
uint8_t* const dlsch_buffer,
const uint16_t N_RB_UL,
const uint8_t input_buffer_length
)
//------------------------------------------------------------------------------
{
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
@@ -69,18 +72,21 @@ unsigned short fill_rar(module_id_t module_idP,
int i,ra_idx = -1;
uint16_t rballoc;
uint8_t mcs,TPC,ULdelay,cqireq;
AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs);
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar == 1) {
ra_idx=i;
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar = 0;
break;
}
for (i=0; i<NB_RA_PROC_MAX; i++) {
if (eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar == 1) {
ra_idx=i;
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar = 0;
break;
}
}
DevAssert( ra_idx != -1 );
//DevAssert( ra_idx != -1 );
if (ra_idx==-1)
return(0);
// subheader fixed
// subheader fixed
rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
@@ -97,8 +103,8 @@ unsigned short fill_rar(module_id_t module_idP,
*/
rar[4] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti>>8);
rar[5] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti&0xff);
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset = 0;
//eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16;
//eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset = 0;
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
rballoc = mac_xface->computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant
@@ -109,28 +115,40 @@ unsigned short fill_rar(module_id_t module_idP,
ULdelay = 0;
cqireq = 0;
rar[2] |= ((mcs&0x8)>>3); // mcs 10
rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1);
rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1);
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",module_idP,frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx,
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID,eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0].preamble_index,
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset);
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",
module_idP, CC_id,
frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx,
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID,eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0].preamble_index,
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset);
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled){
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
eNB_mac_inst[module_idP].subframe, 0, 0);
LOG_I(OPT,"[eNB %d][RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
module_idP, frameP, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
eNB_mac_inst[module_idP].subframe, 0, 0);
LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
module_idP, CC_id, frameP, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID, input_buffer_length);
}
#endif
}
return(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti);
}
uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP, uint8_t *dlsch_buffer,rnti_t *t_crnti,uint8_t preamble_index) {
//------------------------------------------------------------------------------
uint16_t
ue_process_rar(
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
uint8_t* const dlsch_buffer,
rnti_t* const t_crnti,
const uint8_t preamble_index
)
//------------------------------------------------------------------------------
{
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
@@ -142,8 +160,8 @@ uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP, uint8_
}
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",module_idP,frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
rarh->RAPID,preamble_index);
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
rarh->RAPID,preamble_index);
#ifdef DEBUG_RAR
LOG_D(MAC,"[UE %d][RAPROC] rarh->E %d\n",module_idP,rarh->E);
LOG_D(MAC,"[UE %d][RAPROC] rarh->T %d\n",module_idP,rarh->T);
@@ -162,13 +180,12 @@ uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP, uint8_
if (preamble_index == rarh->RAPID) {
*t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti;
UE_mac_inst[module_idP].crnti = *t_crnti;//rar->t_crnti;
//return(rar->Timing_Advance_Command);
return((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
}
else {
UE_mac_inst[module_idP].crnti=0;
return(0xffff);
*t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti;
UE_mac_inst[module_idP].crnti = *t_crnti;//rar->t_crnti;
//return(rar->Timing_Advance_Command);
return((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
} else {
UE_mac_inst[module_idP].crnti=0;
return(0xffff);
}
}
File diff suppressed because it is too large Load Diff
+10 -9
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -47,18 +47,19 @@
#include "PHY_INTERFACE/defs.h"
#include "COMMON/mac_rrc_primitives.h"
const uint32_t BSR_TABLE[BSR_TABLE_SIZE]={0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91,
105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132,
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000};
const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91,
105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132,
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000
};
//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
uint32_t RRC_CONNECTION_FLAG;
UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface;
/// Primary component carrier index of eNB
@@ -66,8 +67,8 @@ int pCC_id[NUMBER_OF_eNB_MAX];
eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
/*
#ifndef USER_MODE
+2
View File
@@ -70,6 +70,7 @@ RRC_OBJS += $(RRC_DIR)/rrc_eNB_ral.o
endif
RRC_OBJS += $(RRC_DIR)/rrc_eNB.o
RRC_OBJS += $(RRC_DIR)/rrc_eNB_UE_context.o
RRC_OBJS += $(RRC_DIR)/rrc_eNB_S1AP.o
ifdef USE_MME
RRC_OBJS += $(RRC_DIR)/rrc_eNB_GTPV1U.o
@@ -98,6 +99,7 @@ L2_INTERFACE_OBJS = $(L2_INTERFACE_DIR)/openair_rrc_L2_interface.o
L2_OBJS=$(addsuffix .o,$(basename $(SOURCES_L2))) $(PHY_INTERFACE_OBJS) $(MAC_OBJS) $(L2_INTERFACE_OBJS)
L2_incl = -I$(OPENAIR2_TOP)
L2_incl = -I$(OPENAIR_DIR)/common/utils/msc
L2_incl += -I$(COMMON_DIR)
L2_incl += -I$(RLC_DIR)
L2_incl += -I$(RLC_AM_DIR)
-346
View File
@@ -1,346 +0,0 @@
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file pdcp.c
* \brief pdcp interface with RLC
* \author Lionel GAUTHIER and Navid Nikaein
* \date 2009
* \version 0.5
*/
#define PDCP_C
//#include "rtos_header.h"
#ifndef USER_MODE
#include <rtai_fifos.h>
#endif
#include "pdcp.h"
#include "LAYER2/RLC/rlc.h"
#include "LAYER2/MAC/extern.h"
//#include "mpls.h"
//#include "w3g4free_extern.h"
#define PDCP_DATA_REQ_DEBUG 1
#define PDCP_DATA_IND_DEBUG 1
//#define IDROMEL_NEMO 1
extern rlc_op_status_t rlc_data_req (module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, mem_block_t*);
//-----------------------------------------------------------------------------
void
pdcp_data_req (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, char* sduP)
{
//-----------------------------------------------------------------------------
mem_block_t *new_sdu = NULL;
// int i;
if ((data_sizeP > 0)) {
if(data_sizeP > MAX_IP_PACKET_SIZE){
msg("[PDCP] REQ FOR SIZE %d !!!Abort\n",data_sizeP);
mac_xface->macphy_exit("");
}
new_sdu = get_free_mem_block (data_sizeP);
if (new_sdu) {
#ifdef PDCP_DATA_REQ_DEBUG
msg("[PDCP] TTI %d, INST %d: PDCP_DATA_REQ size %d RAB %d:\n",Mac_rlc_xface->frame,module_idP,data_sizeP,rab_idP);
// for (i=0;i<20;i++)
// msg("%02X.",((unsigned char*)sduP)[i]);
// msg("\n");
#endif //PDCP_DATA_REQ_DEBUG
// PROCESS OF DECOMPRESSION HERE:
memcpy (&new_sdu->data[0], sduP, data_sizeP);
rlc_data_req(module_idP, rab_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_sizeP, new_sdu);
if(Mac_rlc_xface->Is_cluster_head[module_idP]==1){
Pdcp_stats_tx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++;
Pdcp_stats_tx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP;
}
else{
Pdcp_stats_tx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++;
Pdcp_stats_tx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP;
}
} else {
msg("[PDCP][RAB %d][ERROR] PDCP_DATA_REQ OUT OF MEMORY\n", rab_idP);
}
// free_mem_block (sduP);
} else {
msg("[PDCP][RAB %d][ERROR] PDCP_DATA_REQ SDU SIZE %d\n", rab_idP, data_sizeP);
}
}
//-----------------------------------------------------------------------------
void
pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP)
{
//-----------------------------------------------------------------------------
mem_block_t *new_sdu = NULL;
int i;
if ((data_sizeP > 0)) {
// if(Mac_rlc_xface->Is_cluster_head[0]==1 && Mac_rlc_xface->frame%10==0)
//msg("[PDCP][RAB %d][INST %d] PDCP_DATA_IND size %d\n", rab_idP,module_idP,data_sizeP);
#ifdef PDCP_DATA_IND_DEBUG
msg("[PDCP][RAB %d][INST %d] TTI %d PDCP_DATA_IND size %d\n",
rab_idP,module_idP,Mac_rlc_xface->frame,data_sizeP);
for (i=0;i<20;i++)
msg("%02X.",(unsigned char)sduP->data[i]);
msg("\n");
#endif //PDCP_DATA_IND_DEBUG
new_sdu = get_free_mem_block (data_sizeP + sizeof (pdcp_data_ind_header_t));
if (new_sdu) {
memset (new_sdu->data, 0, sizeof (pdcp_data_ind_header_t));
((pdcp_data_ind_header_t *) new_sdu->data)->rb_id = rab_idP;
((pdcp_data_ind_header_t *) new_sdu->data)->data_size = data_sizeP;
// Here there is no virtualization possible
#ifdef IDROMEL_NEMO
if (Mac_rlc_xface->Is_cluster_head[module_idP] == 0)
((pdcp_data_ind_header_t *) new_sdu->data)->inst = rab_idP/8;
else
((pdcp_data_ind_header_t *) new_sdu->data)->inst = 0;
#else
((pdcp_data_ind_header_t *) new_sdu->data)->inst = module_idP;
#endif
// PROCESS OF DECOMPRESSION HERE:
memcpy (&new_sdu->data[sizeof (pdcp_data_ind_header_t)], &sduP->data[0], data_sizeP);
list_add_tail_eurecom (new_sdu, &pdcp_sdu_list);
if(Mac_rlc_xface->Is_cluster_head[module_idP]==1){
Pdcp_stats_rx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++;
Pdcp_stats_rx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP;
}
else{
Pdcp_stats_rx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++;
Pdcp_stats_rx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP;
}
}
free_mem_block (sduP);
}
}
//-----------------------------------------------------------------------------
void
pdcp_run (void)
{
//-----------------------------------------------------------------------------
// NAS -> PDCP traffic
#ifndef NAS_NETLINK
#ifdef USER_MODE
//#define PDCP_DUMMY_BUFFER_SIZE 38
// unsigned char pdcp_dummy_buffer[PDCP_DUMMY_BUFFER_SIZE];
//msg("[PDCP] PDCP Run Id %d\n",modId);
/*
if(Mac_rlc_xface->frame %1 == 0 && (Mac_rlc_xface->frame > 30)) {
if (Mac_rlc_xface->Is_cluster_head[0] ==0){
pdcp_data_req(0,5,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
pdcp_data_req(0,4,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
// pdcp_data_req(0,4,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
// pdcp_data_req(3,4,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
//pdcp_data_req(4,4,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
}
// if (Mac_rlc_xface->Is_cluster_head[modId] == 1 && Mac_rlc_xface->frame %20 == 0) {
else{
pdcp_data_req(0,20,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
pdcp_data_req(0,21,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
pdcp_data_req(0,12,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
pdcp_data_req(0,13,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
//pdcp_data_req(0,20,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
}
// pdcp_data_req(0,28,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
// pdcp_data_req(0,36,PDCP_DUMMY_BUFFER_SIZE,pdcp_dummy_buffer);
}*/
#endif
#endif
unsigned int diff,i,k,j;
if((Mac_rlc_xface->frame%128)==0) {
// for(i=0;i<NB_INST;i++)
for(i=0;i<NB_UE_INST;i++)
for (j=0;j<NB_CNX_CH;j++)
for(k=0;k<NB_RAB_MAX;k++){
diff = Pdcp_stats_tx_bytes[i][j][k];
Pdcp_stats_tx_bytes[i][j][k]=0;
Pdcp_stats_tx_rate[i][j][k] = (diff*8)>>7;// (Pdcp_stats_tx_rate[i][k]*1+(7*diff*8)>>7)/8;
diff = Pdcp_stats_rx_bytes[i][j][k];
Pdcp_stats_rx_bytes[i][j][k]=0;
Pdcp_stats_rx_rate[i][j][k] =(diff*8)>>7;//(Pdcp_stats_rx_rate[i][k]*1 + (7*diff*8)>>7)/8;
}
}
// printf("[PDCP]Read sdus from NAS\n");
pdcp_fifo_read_input_sdus();
// PDCP -> NAS traffic
pdcp_fifo_flush_sdus();
/*printf("PDCP TTI %d\n", Mac_rlc_xface->frame);
for (i = 0; i < 3; i++) {
printf("[RLC_RRC][MOD ID %d] AM:", i);
for (j = 0; j < RLC_MAX_NUM_INSTANCES_RLC_AM; j++) {
printf("%d", rlc[i].m_rlc_am_array[j].allocation);
}
printf("\n[RLC_RRC][MOD ID %d] UM:", i);
for (j = 0; j < RLC_MAX_NUM_INSTANCES_RLC_UM; j++) {
printf("%d", rlc[i].m_rlc_um_array[j].allocation);
}
printf("\n");
}*/
}
//-----------------------------------------------------------------------------
void
pdcp_config_req (module_id_t module_idP, rb_id_t rab_idP)
{
//-----------------------------------------------------------------------------
//msg ("[PDCP] pdcp_confiq_req()\n");
}
//-----------------------------------------------------------------------------
void
pdcp_config_release (module_id_t module_idP, rb_id_t rab_idP)
{
//-----------------------------------------------------------------------------
//msg ("[PDCP] pdcp_config_release()\n");
}
//-----------------------------------------------------------------------------
int
pdcp_module_init ()
{
//-----------------------------------------------------------------------------
#ifndef USER_MODE
int ret;
ret=rtf_create(PDCP2NAS_FIFO,32768);
if (ret < 0) {
printk("[openair][MAC][INIT] Cannot create PDCP2NAS fifo %d (ERROR %d)\n",PDCP2NAS_FIFO,ret);
return(-1);
}
else{
printk("[openair][MAC][INIT] Created PDCP2NAS fifo %d\n",PDCP2NAS_FIFO);
rtf_reset(PDCP2NAS_FIFO);
}
ret=rtf_create(NAS2PDCP_FIFO,32768);
if (ret < 0) {
printk("[openair][MAC][INIT] Cannot create NAS2PDCP fifo %d (ERROR %d)\n",NAS2PDCP_FIFO,ret);
return(-1);
}
else{
printk("[openair][MAC][INIT] Created NAS2PDCP fifo %d\n",NAS2PDCP_FIFO);
rtf_reset(NAS2PDCP_FIFO);
}
pdcp_2_nas_irq = 0;
pdcp_input_sdu_remaining_size_to_read=0;
pdcp_input_sdu_size_read=0;
#endif
return(0);
}
//-----------------------------------------------------------------------------
void
pdcp_module_cleanup ()
//-----------------------------------------------------------------------------
{
#ifndef USER_MODE
rtf_destroy(NAS2PDCP_FIFO);
rtf_destroy(PDCP2NAS_FIFO);
#endif
}
//-----------------------------------------------------------------------------
void
pdcp_layer_init ()
{
//-----------------------------------------------------------------------------
unsigned int i,j,k;
list_init (&pdcp_sdu_list, NULL);
msg("[PDCP] pdcp_layer_init \n ");
pdcp_output_sdu_bytes_to_write=0;
pdcp_output_header_bytes_to_write=0;
pdcp_input_sdu_remaining_size_to_read=0;
// for (i=0;i<NB_INST;i++)
for (i=0;i<NB_UE_INST;i++)
for (k=0;k<NB_CNX_CH;k++)
for(j=0;j<NB_RAB_MAX;j++){
Pdcp_stats_tx[i][k][j]=0;
Pdcp_stats_tx_bytes[i][k][j]=0;
Pdcp_stats_tx_bytes_last[i][k][j]=0;
Pdcp_stats_tx_rate[i][k][j]=0;
Pdcp_stats_rx[i][k][j]=0;
Pdcp_stats_rx_bytes[i][k][j]=0;
Pdcp_stats_rx_bytes_last[i][k][j]=0;
Pdcp_stats_rx_rate[i][k][j]=0;
}
}
//-----------------------------------------------------------------------------
void
pdcp_layer_cleanup ()
//-----------------------------------------------------------------------------
{
list_free (&pdcp_sdu_list);
}
#ifndef USER_MODE
EXPORT_SYMBOL(pdcp_2_nas_irq);
#endif //USER_MODE
-107
View File
@@ -1,107 +0,0 @@
/*
pdcp.h
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#ifndef __PDCP_H__
# define __PDCP_H__
//-----------------------------------------------------------------------------
# ifdef PDCP_C
# define private_pdcp(x) x
# define protected_pdcp(x) x
# define public_pdcp(x) x
# else
# define private_pdcp(x)
# define public_pdcp(x) extern x
# ifdef PDCP_FIFO_C
# define protected_pdcp(x) extern x
# else
# define protected_pdcp(x)
# endif
# endif
# ifdef PDCP_FIFO_C
# define private_pdcp_fifo(x) x
# define protected_pdcp_fifo(x) x
# define public_pdcp_fifo(x) x
# else
# define private_pdcp_fifo(x)
# define public_pdcp_fifo(x) extern x
# ifdef PDCP_C
# define protected_pdcp_fifo(x) extern x
# else
# define protected_pdcp_fifo(x)
# endif
# endif
//-----------------------------------------------------------------------------
#ifndef NON_ACCESS_STRATUM
//#include "rtos_header.h"
//#include "openair_defs.h"
//#include "platform_types.h"
//#include "platform_constants.h"
#include "UTIL/MEM/mem_block.h"
#include "UTIL/LISTS/list.h"
#include "COMMON/mac_rrc_primitives.h"
#endif //NON_ACCESS_STRATUM
//-----------------------------------------------------------------------------
public_pdcp(unsigned int Pdcp_stats_tx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(void pdcp_data_req (module_id_t, rb_id_t, sdu_size_t, char*);)
public_pdcp(void pdcp_data_ind (module_id_t, rb_id_t, sdu_size_t, mem_block_t*);)
public_pdcp(void pdcp_config_req (module_id_t, rb_id_t);)
public_pdcp(void pdcp_config_release (module_id_t, rb_id_t);)
public_pdcp(void pdcp_run (void);)
public_pdcp(int pdcp_module_init ();)
public_pdcp(void pdcp_module_cleanup ();)
public_pdcp(void pdcp_layer_init ();)
public_pdcp(void pdcp_layer_cleanup ();)
#define PDCP2NAS_FIFO 21
#define NAS2PDCP_FIFO 22
protected_pdcp_fifo(int pdcp_fifo_flush_sdus ();)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus_remaining_bytes ();)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus();)
//-----------------------------------------------------------------------------
typedef struct pdcp_data_req_header_t {
rb_id_t rb_id;
sdu_size_t data_size;
int inst;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_t {
rb_id_t rb_id;
sdu_size_t data_size;
int inst;
} pdcp_data_ind_header_t;
typedef struct pdcp_t {
char allocation;
// here ROHC variables for header compression/decompression
} pdcp_t;
protected_pdcp(signed int pdcp_2_nas_irq;)
protected_pdcp(pdcp_t pdcp_array[MAX_MODULES][MAX_RAB];)
protected_pdcp(sdu_size_t pdcp_output_sdu_bytes_to_write;)
protected_pdcp(sdu_size_t pdcp_output_header_bytes_to_write;)
protected_pdcp(list_t pdcp_sdu_list;)
protected_pdcp(int pdcp_sent_a_sdu;)
protected_pdcp(pdcp_data_req_header_t pdcp_input_header;)
protected_pdcp(char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];)
protected_pdcp(sdu_size_t pdcp_input_index_header;)
protected_pdcp(sdu_size_t pdcp_input_sdu_size_read;)
protected_pdcp(sdu_size_t pdcp_input_sdu_remaining_size_to_read;)
#endif
@@ -1,33 +0,0 @@
/***************************************************************************
pdcp_control_primitives.c
-------------------
begin : Mon Dec 10 2001
copyright : (C) 2001 by EURECOM
email : Lionel.Gauthier@eurecom.fr
-------------------
description
This file contains the functions used for configuration of pdcp
***************************************************************************/
#include "rtos_header.h"
#include "platform.h"
#include "protocol_vars_extern.h"
#include "print.h"
//-----------------------------------------------------------------------------
#include "rlc.h"
#include "pdcp.h"
#include "debug_l2.h"
//-----------------------------------------------------------------------------
void
configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP)
{
//-----------------------------------------------------------------------------
mem_block *mb;
mb = get_free_mem_block (sizeof (struct cpdcp_primitive));
((struct cpdcp_primitive *) mb->data)->type = CPDCP_CONFIG_REQ;
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_sap = rlcP;
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_type_sap = rlc_sap_typeP;
((struct cpdcp_primitive *) mb->data)->primitive.config_req.header_compression_type = header_compression_typeP;
send_pdcp_control_primitive (pdcpP, mb);
}
@@ -1,16 +0,0 @@
/***************************************************************************
pdcp_control_primitives_proto_extern.h
-------------------
begin : Mon Dec 10 2001
copyright : (C) 2001 by EURECOM
email : Lionel.Gauthier@eurecom.fr
-------------------
description
This file contains the prototypes of functions used for configuration of pdcp
***************************************************************************/
#ifndef PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
# define PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
# include "pdcp.h"
void rrc_configure_pdcp (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP);
#endif
-44
View File
@@ -1,44 +0,0 @@
/*
pdcp_entity.h
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#ifndef __PDCP_ENTITY_H__
# define __PDCP_ENTITY_H__
# include "list.h"
struct pdcp_entity {
unsigned short id; // for resource management purpose
unsigned char allocation;
void *rlc_sap;
//-----------------------------
// C-SAP
//-----------------------------
list c_sap;
//-----------------------------
// tranmission
//-----------------------------
list input_sdu_list;
void *rlc;
//-----------------------------
// receiver
//-----------------------------
//struct list output_sdu_list;
#ifdef ROHC
void (*pdcp_process_input_sdus) (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
#else
void (*pdcp_process_input_sdus) (struct pdcp_entity *pdcpP);
#endif
unsigned char rb_id; // for traces
unsigned char rlc_type_sap; // am, um, tr
struct rb_dispatcher *rb_dispatch;
};
#endif
-455
View File
@@ -1,455 +0,0 @@
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file pdcp_fifo.c
* \brief pdcp interface with linux IP interface
* \author Lionel GAUTHIER and Navid Nikaein
* \date 2009
* \version 0.5
* \warning This component can be runned only in user-space
* @ingroup pdcp
*/
#define PDCP_FIFO_C
#include "pdcp.h"
#ifdef USER_MODE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define rtf_put write
#define rtf_get read
#else
#include <rtai_fifos.h>
#endif //USER_MODE
#include "../MAC/extern.h"
#include "SIMULATION/ETH_TRANSPORT/extern.h"
#define PDCP_DEBUG 1
//#define IDROMEL_NEMO 1
#ifdef USER_MODE
#include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h"
#endif
#ifdef NAS_NETLINK
#include <sys/socket.h>
#include <linux/netlink.h>
extern struct sockaddr_nl nas_src_addr, nas_dest_addr;
extern struct nlmsghdr *nas_nlh;
extern struct iovec nas_iov;
extern int nas_sock_fd;
extern struct msghdr nas_msg;
#define MAX_PAYLOAD 1600 /* maximum payload size*/
unsigned char pdcp_read_state = 0;
char pdcp_read_payload[MAX_PAYLOAD];
#endif
pdcp_data_req_header_t pdcp_read_header;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int
pdcp_fifo_flush_sdus ()
{
//-----------------------------------------------------------------------------
mem_block_t *sdu = list_get_head (&pdcp_sdu_list);
int bytes_wrote = 0;
int pdcp_nb_sdu_sent = 0;
uint8_t cont = 1;
int ret;
while ((sdu) && (cont)) {
#ifdef USER_MODE
// asjust the instance id when passing sdu to IP
((pdcp_data_ind_header_t *)(sdu->data))->inst = (((pdcp_data_ind_header_t *)(sdu->data))->inst >= NB_eNB_INST) ?
((pdcp_data_ind_header_t *)(sdu->data))->inst - NB_eNB_INST +oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local :// UE
((pdcp_data_ind_header_t *)(sdu->data))->inst - oai_emulation.info.first_ue_local; // ENB
#else
((pdcp_data_ind_header_t *)(sdu->data))->inst = 0;
#endif
#ifdef PDCP_DEBUG
msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n",
Mac_rlc_xface->frame,
((pdcp_data_ind_header_t *)(sdu->data))->inst,
((pdcp_data_ind_header_t *)(sdu->data))->data_size,
((pdcp_data_ind_header_t *)(sdu->data))->rb_id);
#endif //PDCP_DEBUG
cont = 0;
if (!pdcp_output_sdu_bytes_to_write) {
if (!pdcp_output_header_bytes_to_write) {
pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t);
}
#ifndef USER_MODE
bytes_wrote = rtf_put (PDCP2NAS_FIFO,
&(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
pdcp_output_header_bytes_to_write);
#else
#ifdef NAS_NETLINK
#ifdef LINUX
memcpy(NLMSG_DATA(nas_nlh), &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
pdcp_output_header_bytes_to_write);
nas_nlh->nlmsg_len = pdcp_output_header_bytes_to_write;
#endif //LINUX
#endif //NAS_NETLINK
bytes_wrote = pdcp_output_header_bytes_to_write;
#endif //USER_MODE
#ifdef PDCP_DEBUG
msg("[PDCP][INFO] TTI %d Sent %d Bytes of header to Nas_mesh\n",
Mac_rlc_xface->frame,
bytes_wrote);
#endif //PDCP_DEBUG
if (bytes_wrote > 0) {
pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote;
if (!pdcp_output_header_bytes_to_write) { // continue with sdu
pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu->data)->data_size;
#ifndef USER_MODE
bytes_wrote = rtf_put (PDCP2NAS_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write);
#else
#ifdef NAS_NETLINK
#ifdef LINUX
memcpy(NLMSG_DATA(nas_nlh)+sizeof(pdcp_data_ind_header_t), &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write);
nas_nlh->nlmsg_len += pdcp_output_sdu_bytes_to_write;
ret = sendmsg(nas_sock_fd,&nas_msg,0);
if (ret<0) {
msg("[PDCP_FIFOS] sendmsg returns %d\n",ret);
perror("error code:");
mac_xface->macphy_exit("");
break;
}
#endif // LINUX
#endif //NAS_NETLINK
bytes_wrote= pdcp_output_sdu_bytes_to_write;
#endif // USER_MODE
#ifdef PDCP_DEBUG
msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Sent %d Bytes of data from rab %d to Nas_mesh\n",
Mac_rlc_xface->frame,
((pdcp_data_ind_header_t *)(sdu->data))->inst,
bytes_wrote,
((pdcp_data_ind_header_t *)(sdu->data))->rb_id);
#endif //PDCP_DEBUG
if (bytes_wrote > 0) {
pdcp_output_sdu_bytes_to_write -= bytes_wrote;
if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU
// msg("rb sent a sdu qos_sap %d\n",sapiP);
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu);
cont = 1;
pdcp_nb_sdu_sent += 1;
sdu = list_get_head (&pdcp_sdu_list);
}
} else {
msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n");
}
} else {
msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n");
}
}
} else {
// continue writing sdu
#ifndef USER_MODE
bytes_wrote = rtf_put (PDCP2NAS_FIFO,
(uint8_t *) (&(sdu->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu->data)->data_size - pdcp_output_sdu_bytes_to_write])),
pdcp_output_sdu_bytes_to_write);
#else // USER_MODE
bytes_wrote = pdcp_output_sdu_bytes_to_write;
#endif // USER_MODE
if (bytes_wrote > 0) {
pdcp_output_sdu_bytes_to_write -= bytes_wrote;
if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU
//PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n");
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu);
cont = 1;
pdcp_nb_sdu_sent += 1;
sdu = list_get_head (&pdcp_sdu_list);
// msg("rb sent a sdu from rab\n");
}
}
}
}
#ifndef USER_MODE
if ((pdcp_nb_sdu_sent)) {
if ((pdcp_2_nas_irq > 0)) {
#ifdef PDCP_DEBUG
msg("[PDCP][INFO] TTI %d : Trigger NAS RX interrupt\n",
Mac_rlc_xface->frame);
#endif //PDCP_DEBUG
rt_pend_linux_srq (pdcp_2_nas_irq);
} else {
msg ("[PDCP] TTI %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n",
Mac_rlc_xface->frame,
pdcp_2_nas_irq);
}
}
#endif //USER_MODE
return pdcp_nb_sdu_sent;
}
//-----------------------------------------------------------------------------
/*
* returns a positive value if whole bytes that had to be read were read
* returns zero value if whole bytes that had to be read were not read at all
* returns a negative value if an error was encountered while reading the rt fifo
*/
int
pdcp_fifo_read_input_sdus_remaining_bytes ()
{
//-----------------------------------------------------------------------------
sdu_size_t bytes_read=0;
if (pdcp_input_sdu_remaining_size_to_read > 0) {
// printk("[PDCP][INFO] read_input_sdus pdcp_input_sdu_remaining_size_to_read = %d \n", pdcp_input_sdu_remaining_size_to_read);
bytes_read = rtf_get (NAS2PDCP_FIFO,
&(pdcp_input_sdu_buffer[pdcp_input_sdu_size_read]),
pdcp_input_sdu_remaining_size_to_read);
//printk("[PDCP][INFO] read fifo returned %d \n", bytes_read);
if (bytes_read > 0) {
//msg("[PDCP_FIFOS] Read %d remaining Bytes of data from Nas_mesh\n",bytes_read);
pdcp_input_sdu_remaining_size_to_read = pdcp_input_sdu_remaining_size_to_read - bytes_read;
pdcp_input_sdu_size_read = pdcp_input_sdu_size_read + bytes_read;
if (pdcp_input_sdu_remaining_size_to_read != 0) {
return 0;
} else {
#ifdef PDCP_DEBUG
msg("[PDCP][INFO] TTI %d: IP->RADIO RECEIVED COMPLETE SDU size %d inst %d rb %d\n",
Mac_rlc_xface->frame,
pdcp_input_sdu_size_read,
pdcp_input_header.inst,
pdcp_input_header.rb_id);
#endif //PDCP_DEBUG
pdcp_input_sdu_size_read = 0;
#ifdef IDROMEL_NEMO
pdcp_read_header.inst = 0;
#endif
pdcp_data_req (pdcp_input_header.inst,
pdcp_input_header.rb_id,
pdcp_input_header.data_size,
pdcp_input_sdu_buffer);
// not necessary
//memset(pdcp_input_sdu_buffer, 0, MAX_IP_PACKET_SIZE);
return 1;
}
} else {
return bytes_read;
}
}
return 1;
}
#ifndef NAS_NETLINK
//-----------------------------------------------------------------------------
int
pdcp_fifo_read_input_sdus ()
{
//-----------------------------------------------------------------------------
int cont;
int bytes_read;
// if remaining bytes to read
if (pdcp_fifo_read_input_sdus_remaining_bytes () > 0) {
// all bytes that had to be read for a SDU were read
// if not overflow of list, try to get new sdus from rt fifo
cont = 1;
while (cont > 0) {
bytes_read = rtf_get (NAS2PDCP_FIFO,
&(((uint8_t *) & pdcp_input_header)[pdcp_input_index_header]),
sizeof (pdcp_data_req_header_t) - pdcp_input_index_header);
if (bytes_read > 0) {
#ifdef PDCP_DEBUG
msg("[PDCP_FIFOS] TTI %d Read %d Bytes of data (header %d) from Nas_mesh\n",
Mac_rlc_xface->frame,
bytes_read,
sizeof(pdcp_data_req_header_t));
#endif
pdcp_input_index_header += bytes_read;
if (pdcp_input_index_header == sizeof (pdcp_data_req_header_t)) {
#ifdef PDCP_DEBUG
msg("[PDCP] TTI %d IP->RADIO READ HEADER sdu size %d\n",
Mac_rlc_xface->frame,
pdcp_input_header.data_size);
#endif
pdcp_input_index_header = 0;
if (pdcp_input_header.data_size < 0) {
msg("[PDCP][FATAL ERROR] READ_FIFO: DATA_SIZE %d < 0\n",pdcp_input_header.data_size);
mac_xface->macphy_exit("");
return 0;
}
pdcp_input_sdu_remaining_size_to_read = pdcp_input_header.data_size;
pdcp_input_sdu_size_read = 0;
// we know the size of the sdu, so read the sdu;
cont = pdcp_fifo_read_input_sdus_remaining_bytes ();
} else {
cont = 0;
}
// error while reading rt fifo
} else {
cont = 0;
}
}
}
return 0;
}
#else //NAS_NETLINK
//-----------------------------------------------------------------------------
int
pdcp_fifo_read_input_sdus ()
{
//-----------------------------------------------------------------------------
int cont;
int bytes_read;
int len;
if (pdcp_read_state == 0) {
#ifdef LINUX
len = recvmsg(nas_sock_fd, &nas_msg, 0);
#else
len = -1;
#endif
if (len<0) {
//printf("[PDCP][NETLINK %d] nothing in pdcp NAS socket\n", nas_sock_fd);
}
else {
#ifdef PDCP_DEBUG
#ifdef LINUX
printf("[PDCP][NETLINK] Received socket with length %d (nlmsg_len = %d)\n",len,nas_nlh->nlmsg_len-sizeof(struct nlmsghdr));
#endif PDCP_DEBUG
#ifdef PDCP_DEBUG
printf("[PDCP][NETLINK] nlmsg_len = %d (%d,%d)\n",nas_nlh->nlmsg_len,
sizeof(pdcp_data_req_header_t),
sizeof(struct nlmsghdr));
#endif LINUX
#endif PDCP_DEBUG
}
#ifdef LINUX
if (nas_nlh->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
pdcp_read_state = 1; //get
memcpy((void *)&pdcp_read_header,
(void *)NLMSG_DATA(nas_nlh),
sizeof(pdcp_data_req_header_t));
}
#else //LINUX
pdcp_read_state = 1;
#endif //LINUX
}
if (pdcp_read_state == 1) {
#ifdef LINUX
len = recvmsg(nas_sock_fd, &nas_msg, 0);
#else
len = -1;
#endif //LINUX
if (len<0) {
// nothing in pdcp NAS socket
} else {
pdcp_read_state = 0;
//print_active_requests()
#ifdef LINUX
memcpy(pdcp_read_payload,
(unsigned char *)NLMSG_DATA(nas_nlh),
nas_nlh->nlmsg_len - sizeof(struct nlmsghdr));
#endif
#ifdef IDROMEL_NEMO
pdcp_read_header.inst = 0;
#endif
pdcp_read_header.inst = (pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) ?
pdcp_read_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
pdcp_read_header.inst + oai_emulation.info.first_enb_local;
#ifdef PDCP_DEBUG
printf("[PDCP][NETLINK][IP->PDCP] TTI %d, INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
Mac_rlc_xface->frame,
pdcp_read_header.inst,
len,
nas_nlh->nlmsg_len-sizeof(struct nlmsghdr),
pdcp_read_header.rb_id);
#endif PDCP_DEBUG
pdcp_data_req(pdcp_read_header.inst,
pdcp_read_header.rb_id,
pdcp_read_header.data_size,
pdcp_read_payload);
}
}
}
#endif
-77
View File
@@ -1,77 +0,0 @@
/*
pdcp_primitives.h
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#ifndef __PDCP_PRIMITIVES_H__
# define __PDCP_PRIMITIVES_H__
# include "platform.h"
//----------------------------------------------------------
// primitives
//----------------------------------------------------------
# define PDCP_DATA_REQ 0x01
# define PDCP_DATA_IND 0x02
//----------------------------------------------------------
// control primitives
//----------------------------------------------------------
# define CPDCP_CONFIG_REQ 0x04
# define CPDCP_RELEASE_REQ 0x08
# define CPDCP_SN_REQ 0x10
# define CPDCP_RELOC_REQ 0x20
# define CPDCP_RELOC_CNF 0x40
//----------------------------------------------------------
// primitives definition
//----------------------------------------------------------
struct pdcp_data_req {
uint16_t rb_id;
uint16_t data_size;
};
struct pdcp_data_ind {
uint16_t rb_id;
uint16_t data_size;
};
//----------------------------------------------------------
// control primitives definition
//----------------------------------------------------------
// TO DO
struct cpdcp_config_req {
void *rlc_sap;
uint8_t rlc_type_sap; // am, um, tr
uint8_t header_compression_type;
};
struct cpdcp_release_req {
void *rlc_sap;
};
struct cpdcp_sn_req {
uint32_t sn;
};
struct cpdcp_relloc_req {
uint32_t receive_sn;
};
struct cpdcp_relloc_conf {
uint32_t receive_sn;
uint32_t send_sn;
};
struct cpdcp_primitive {
uint8_t type;
union {
struct cpdcp_config_req config_req;
struct cpdcp_release_req release_req;
struct cpdcp_sn_req sn_req;
struct cpdcp_relloc_req relloc_req;
struct cpdcp_relloc_conf relloc_conf;
} primitive;
};
#endif
-43
View File
@@ -1,43 +0,0 @@
/*
pdcp_proto_extern.h
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#ifndef __PDCP_PROTO_EXTERN_H__
# define __PDCP_PROTO_EXTERN_H__
//# include "pdcp_entity.h"
//# include "rb_mux.h"
# include "mem_block.h"
#ifdef ROHC
extern void pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP);
extern void pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP);
extern void send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block * cprimitiveP);
extern void control_pdcp (struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_high(struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_am (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void pdcp_process_output_sdus (struct pdcp_entity *pdcpP, mem_block * sduP, uint8_t rb_idP);
extern void pdcp_process_output_sdus_high (struct pdcp_entity *pdcpP, mem_block * sduP, uint16_t data_sizeP, uint16_t rb_idP);
extern void pdcp_process_input_sdus_um (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP);
extern void *pdcp_tx (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern int reception_from_rohc_mt(void);
extern int reception_from_rohc_bs(void);
#else
extern void pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP);
extern void pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP);
extern void send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block * cprimitiveP);
extern void control_pdcp (struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_am (struct pdcp_entity *pdcpP);
extern void pdcp_process_output_sdus (struct pdcp_entity *pdcpP, mem_block * sduP, uint8_t rb_idP);
extern void pdcp_process_input_sdus_um (struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP);
extern void init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP);
extern void *pdcp_tx (void *argP);
#endif
#endif
File diff suppressed because it is too large Load Diff
+115 -79
View File
@@ -21,19 +21,24 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file pdcp.c
/*! \file LAYER2/PDCP_v10.1.0/pdcp.h
* \brief pdcp interface with RLC, RRC
* \author Lionel GAUTHIER and Navid Nikaein
* \date 2009-2012
* \version 1.0
*/
/** @defgroup _pdcp PDCP
* @ingroup _oai2
* @{
*/
#ifndef __PDCP_H__
# define __PDCP_H__
//-----------------------------------------------------------------------------
@@ -66,9 +71,9 @@
# endif
//-----------------------------------------------------------------------------
#ifndef NON_ACCESS_STRATUM
#include "UTIL/MEM/mem_block.h"
#include "UTIL/LISTS/list.h"
#include "COMMON/mac_rrc_primitives.h"
#include "UTIL/MEM/mem_block.h"
#include "UTIL/LISTS/list.h"
#include "COMMON/mac_rrc_primitives.h"
#endif //NON_ACCESS_STRATUM
//-----------------------------------------------------------------------------
#include "COMMON/platform_constants.h"
@@ -89,6 +94,11 @@ extern pthread_mutex_t pdcp_mutex;
extern pthread_cond_t pdcp_cond;
extern int pdcp_instance_cnt;
#define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] "
#define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\
(pDCP_Pp->is_srb) ? "SRB" : "DRB",\
pDCP_Pp->rb_id
int init_pdcp_thread(void);
void cleanup_pdcp_thread(void);
@@ -102,19 +112,19 @@ public_pdcp(unsigned int Pdcp_stats_rx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_M
public_pdcp(unsigned int Pdcp_stats_rx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
typedef struct pdcp_stats_t {
typedef struct pdcp_stats_s {
time_stats_t pdcp_run;
time_stats_t data_req;
time_stats_t data_ind;
time_stats_t apply_security; //
time_stats_t apply_security; //
time_stats_t validate_security;
time_stats_t pdcp_ip;
time_stats_t ip_pdcp; // separte thread
}pdcp_stats_t; // common to eNB and UE
} pdcp_stats_t; // common to eNB and UE
typedef struct pdcp_t {
boolean_t instanciated_instance;
typedef struct pdcp_s {
//boolean_t instanciated_instance;
uint16_t header_compression_profile;
/* SR: added this flag to distinguish UE/eNB instance as pdcp_run for virtual
@@ -158,7 +168,7 @@ typedef struct pdcp_t {
pdcp_hfn_t tx_hfn;
pdcp_hfn_t rx_hfn;
pdcp_hfn_offset_t rx_hfn_offset; // related to sn mismatch
/*
* SN of the last PDCP SDU delivered to upper layers
*/
@@ -178,12 +188,12 @@ typedef struct pdcp_t {
/*
* decipher using a different rx_hfn
*/
} pdcp_t;
#if defined(Rel10)
typedef struct pdcp_mbms_t {
typedef struct pdcp_mbms_s {
boolean_t instanciated_instance;
rb_id_t rb_id;
} pdcp_mbms_t;
@@ -211,14 +221,14 @@ typedef struct pdcp_mbms_t {
* @ingroup _pdcp
*/
public_pdcp(boolean_t pdcp_data_req(
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
const confirm_t confirmP, \
const sdu_size_t sdu_buffer_size,
unsigned char* const sdu_buffer,
const pdcp_transmission_mode_t mode));
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
const confirm_t confirmP, \
const sdu_size_t sdu_buffer_size,
unsigned char* const sdu_buffer,
const pdcp_transmission_mode_t mode));
/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
* \brief This functions handles data transfer indications coming from RLC
@@ -234,12 +244,12 @@ public_pdcp(boolean_t pdcp_data_req(
* @ingroup _pdcp
*/
public_pdcp(boolean_t pdcp_data_ind(
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t* const sdu_buffer));
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t* const sdu_buffer));
/*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t)
* \brief This functions initializes relevant PDCP entity
@@ -252,11 +262,11 @@ public_pdcp(boolean_t pdcp_data_ind(
* @ingroup _pdcp
*/
public_pdcp(void rrc_pdcp_config_req (
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const uint32_t actionP,
const rb_id_t rb_idP,
const uint8_t security_modeP);)
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
const uint32_t actionP,
const rb_id_t rb_idP,
const uint8_t security_modeP);)
/*! \fn bool rrc_pdcp_config_asn1_req (const protocol_ctxt_t* const , SRB_ToAddModList_t* srb2add_list, DRB_ToAddModList_t* drb2add_list, DRB_ToReleaseList_t* drb2release_list)
* \brief Function for RRC to configure a Radio Bearer.
@@ -272,19 +282,19 @@ public_pdcp(void rrc_pdcp_config_req (
* \return A status about the processing, OK or error code.
*/
public_pdcp(
boolean_t rrc_pdcp_config_asn1_req (
const protocol_ctxt_t* const ctxt_pP,
SRB_ToAddModList_t *const srb2add_list,
DRB_ToAddModList_t *const drb2add_list,
DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
boolean_t rrc_pdcp_config_asn1_req (
const protocol_ctxt_t* const ctxt_pP,
SRB_ToAddModList_t *const srb2add_list,
DRB_ToAddModList_t *const drb2add_list,
DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#ifdef Rel10
,PMCH_InfoList_r9_t *pmch_InfoList_r9
,PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
));
));
/*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode)
* \brief Function for RRC to configure a Radio Bearer.
@@ -307,30 +317,30 @@ boolean_t rrc_pdcp_config_asn1_req (
* \return A status about the processing, OK or error code.
*/
public_pdcp(boolean_t pdcp_config_req_asn1 (
const protocol_ctxt_t* const ctxt_pP,
pdcp_t *const pdcp_pP,
const srb_flag_t srb_flagP,
const rlc_mode_t rlc_mode,
const uint32_t action,
const uint16_t lc_id,
const uint16_t mch_id,
const rb_id_t rb_id,
const uint8_t rb_sn,
const uint8_t rb_report,
const uint16_t header_compression_profile,
const uint8_t security_mode,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc));
const protocol_ctxt_t* const ctxt_pP,
pdcp_t *const pdcp_pP,
const srb_flag_t srb_flagP,
const rlc_mode_t rlc_mode,
const uint32_t action,
const uint16_t lc_id,
const uint16_t mch_id,
const rb_id_t rb_id,
const uint8_t rb_sn,
const uint8_t rb_report,
const uint16_t header_compression_profile,
const uint8_t security_mode,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc));
/*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP)
* \brief Function for RRC to configure a Radio Bearer clear all PDCP resources for a particular UE
* \brief Function for RRC to configure a Radio Bearer clear all PDCP resources for a particular UE
* \param[in] ctxt_pP Running context.
* \return A status about the processing, OK or error code.
*/
public_pdcp(boolean_t pdcp_remove_UE(
const protocol_ctxt_t* const ctxt_pP));
const protocol_ctxt_t* const ctxt_pP));
/*! \fn void rrc_pdcp_config_release( const protocol_ctxt_t* const, rb_id_t)
* \brief This functions is unused
@@ -350,24 +360,26 @@ public_pdcp(boolean_t pdcp_remove_UE(
* @ingroup _pdcp
*/
public_pdcp(void pdcp_run (
const protocol_ctxt_t* const ctxt_pP);)
const protocol_ctxt_t* const ctxt_pP);)
public_pdcp(int pdcp_module_init (void);)
public_pdcp(void pdcp_module_cleanup (void);)
public_pdcp(void pdcp_layer_init (void);)
public_pdcp(void pdcp_layer_cleanup (void);)
#if defined(PDCP_USE_NETLINK_QUEUES)
public_pdcp(int pdcp_netlink_init (void);)
#define PDCP2NAS_FIFO 21
#define NAS2PDCP_FIFO 22
#endif
#define PDCP2NW_DRIVER_FIFO 21
#define NW_DRIVER2PDCP_FIFO 22
protected_pdcp_fifo(int pdcp_fifo_flush_sdus (
const protocol_ctxt_t* const ctxt_pP);)
const protocol_ctxt_t* const ctxt_pP);)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus_remaining_bytes (
const protocol_ctxt_t* const ctxt_pP);)
const protocol_ctxt_t* const ctxt_pP);)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus (
const protocol_ctxt_t* const ctxt_pP);)
const protocol_ctxt_t* const ctxt_pP);)
protected_pdcp_fifo(void pdcp_fifo_read_input_sdus_from_otg (
const protocol_ctxt_t* const ctxt_pP);)
const protocol_ctxt_t* const ctxt_pP);)
//-----------------------------------------------------------------------------
@@ -391,10 +403,10 @@ typedef struct pdcp_data_ind_header_s {
} pdcp_data_ind_header_t;
struct pdcp_netlink_element_s {
pdcp_data_req_header_t pdcp_read_header;
pdcp_data_req_header_t pdcp_read_header;
/* Data part of the message */
uint8_t *data;
/* Data part of the message */
uint8_t *data;
};
#if 0
@@ -417,26 +429,31 @@ typedef struct pdcp_missing_pdu_info_t {
/*
* Reordering_Window: half of the PDCP SN space
*/
*/
#define REORDERING_WINDOW_SN_5BIT 16
#define REORDERING_WINDOW_SN_7BIT 64
#define REORDERING_WINDOW_SN_12BIT 2048
/*
* SN size
/*
* SN size
*/
#define PDCP_SN_5BIT 5
#define PDCP_SN_7BIT 7
#define PDCP_SN_12BIT 12
protected_pdcp(signed int pdcp_2_nas_irq;)
public_pdcp(pdcp_stats_t UE_pdcp_stats[NUMBER_OF_UE_MAX];)
public_pdcp(pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];)
protected_pdcp(pdcp_t pdcp_array_srb_ue[NUMBER_OF_UE_MAX][2];)
protected_pdcp(pdcp_t pdcp_array_drb_ue[NUMBER_OF_UE_MAX][maxDRB];)
public_pdcp(pdcp_t pdcp_array_srb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][2];)
protected_pdcp(pdcp_t pdcp_array_drb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][maxDRB];)
//protected_pdcp(pdcp_t pdcp_array_srb_ue[NUMBER_OF_UE_MAX][2];)
//protected_pdcp(pdcp_t pdcp_array_drb_ue[NUMBER_OF_UE_MAX][maxDRB];)
//public_pdcp(pdcp_t pdcp_array_srb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][2];)
//protected_pdcp(pdcp_t pdcp_array_drb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][maxDRB];)
// for UE code conly
protected_pdcp(rnti_t pdcp_UE_UE_module_id_to_rnti[NUMBER_OF_UE_MAX];)
protected_pdcp(rnti_t pdcp_eNB_UE_instance_to_rnti[NUMBER_OF_UE_MAX];) // for noS1 mode
protected_pdcp(unsigned int pdcp_eNB_UE_instance_to_rnti_index;)
#if defined(Rel10)
public_pdcp(pdcp_mbms_t pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h
public_pdcp(pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h
@@ -450,5 +467,24 @@ protected_pdcp(unsigned char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
protected_pdcp(sdu_size_t pdcp_input_index_header;)
protected_pdcp(sdu_size_t pdcp_input_sdu_size_read;)
protected_pdcp(sdu_size_t pdcp_input_sdu_remaining_size_to_read;)
#define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
((hash_key_t)mODULE_iD | \
(((hash_key_t)(rNTI)) << 8) | \
(((hash_key_t)(iS_eNB)) << 24) | \
(((hash_key_t)(rB_iD)) << 25) | \
(((hash_key_t)(iS_sRB)) << 33))
// service id max val is maxServiceCount = 16 (asn1_constants.h)
#define PDCP_COLL_KEY_MBMS_VALUE(mODULE_iD, rNTI, iS_eNB, sERVICE_ID, sESSION_ID) \
((hash_key_t)mODULE_iD | \
(((hash_key_t)(rNTI)) << 8) | \
(((hash_key_t)(iS_eNB)) << 24) | \
(((hash_key_t)(sERVICE_ID)) << 32) | \
(((hash_key_t)(sESSION_ID)) << 37) | \
(((hash_key_t)(0x0000000000000001)) << 63))
public_pdcp(hash_table_t *pdcp_coll_p;)
#endif
/*@}*/
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -32,8 +32,8 @@
begin : Mon Dec 10 2001
email : Lionel.Gauthier@eurecom.fr
-------------------
description
This file contains the functions used for configuration of pdcp
description
This file contains the functions used for configuration of pdcp
***************************************************************************/
#include "rtos_header.h"
@@ -48,7 +48,7 @@
void
configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block *mb;
mb = get_free_mem_block (sizeof (struct cpdcp_primitive));
@@ -21,13 +21,13 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
pdcp_control_primitives_proto_extern.h
pdcp_control_primitives_proto_extern.h
-------------------
begin : Mon Dec 10 2001
email : Lionel.Gauthier@eurecom.fr
File diff suppressed because it is too large Load Diff
+167 -134
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -38,6 +38,7 @@
* @ingroup pdcp
*/
#define _GNU_SOURCE // required for pthread_setname_np()
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
@@ -66,6 +67,8 @@
#include "pdcp.h"
#include "pdcp_primitives.h"
#include "msc.h"
#define PDCP_QUEUE_NB_ELEMENTS 200
@@ -75,6 +78,7 @@ extern struct iovec nas_iov_rx;
extern int nas_sock_fd;
extern struct msghdr nas_msg_rx;
#if defined(PDCP_USE_NETLINK_QUEUES)
static pthread_t pdcp_netlink_thread;
/* We use lock-free queues between the User-plane driver running in kernel-space
@@ -86,18 +90,24 @@ static struct lfds611_queue_state **pdcp_netlink_queue_ue = NULL;
static uint32_t *pdcp_netlink_nb_element_enb = NULL;
static uint32_t *pdcp_netlink_nb_element_ue = NULL;
time_stats_t ip_pdcp_stats_tmp;
time_stats_t ip_pdcp_stats_tmp;
static void *pdcp_netlink_thread_fct(void *arg);
int pdcp_netlink_init(void) {
//-----------------------------------------------------------------------------
int
pdcp_netlink_init(
void
)
//-----------------------------------------------------------------------------
{
int i;
int nb_inst_enb;
int nb_inst_ue;
pthread_attr_t attr;
struct sched_param sched_param;
reset_meas(&ip_pdcp_stats_tmp);
#if defined(USER_MODE) && defined(OAI_EMU)
nb_inst_enb = oai_emulation.info.nb_enb_local;
@@ -106,188 +116,211 @@ int pdcp_netlink_init(void) {
nb_inst_enb = 1;
nb_inst_ue = 1;
#endif
#if defined(LINK_PDCP_TO_GTPV1U)
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
nb_inst_enb = 0;
LOG_I(PDCP, "[NETLINK] Creating 0 queues for eNB Netlink -> PDCP communication\n");
#else
#warning " LG: When there will be handover in, there will problems because dim is based on local nums of ues"
pdcp_netlink_queue_enb = calloc(nb_inst_enb, sizeof(struct lfds611_queue_state*));
pdcp_netlink_nb_element_enb = malloc(nb_inst_enb * sizeof(uint32_t));
LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb);
for (i = 0; i < nb_inst_enb; i++) {
pdcp_netlink_nb_element_enb[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
pdcp_netlink_nb_element_enb[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
}
#endif
if (nb_inst_ue > 0) {
pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state*));
pdcp_netlink_nb_element_ue = malloc(nb_inst_ue * sizeof(uint32_t));
pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state*));
pdcp_netlink_nb_element_ue = malloc(nb_inst_ue * sizeof(uint32_t));
LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue);
LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue);
for (i = 0; i < nb_inst_ue; i++) {
pdcp_netlink_nb_element_ue[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_ue[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for UE Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
for (i = 0; i < nb_inst_ue; i++) {
pdcp_netlink_nb_element_ue[i] = 0;
if (lfds611_queue_new(&pdcp_netlink_queue_ue[i], PDCP_QUEUE_NB_ELEMENTS) < 0) {
LOG_E(PDCP, "Failed to create new FIFO for UE Netlink -> PDCP communcation instance %d\n", i);
exit(EXIT_FAILURE);
}
}
}
if ((nb_inst_ue + nb_inst_enb) > 0) {
if (pthread_attr_init(&attr) != 0) {
LOG_E(PDCP, "[NETLINK]Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (pthread_attr_init(&attr) != 0) {
LOG_E(PDCP, "[NETLINK]Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
sched_param.sched_priority = 10;
sched_param.sched_priority = 10;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &sched_param);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &sched_param);
/* Create one thread that fetchs packets from the netlink.
* When the netlink fifo is full, packets are silently dropped, this behaviour
* should be avoided if we want a reliable link.
*/
if (pthread_create(&pdcp_netlink_thread, &attr, pdcp_netlink_thread_fct, NULL) != 0) {
LOG_E(PDCP, "[NETLINK]Failed to create new thread for Netlink/PDCP communication (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
/* Create one thread that fetchs packets from the netlink.
* When the netlink fifo is full, packets are silently dropped, this behaviour
* should be avoided if we want a reliable link.
*/
if (pthread_create(&pdcp_netlink_thread, &attr, pdcp_netlink_thread_fct, NULL) != 0) {
LOG_E(PDCP, "[NETLINK]Failed to create new thread for Netlink/PDCP communication (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
pthread_setname_np( pdcp_netlink_thread, "PDCP netlink" );
}
return 0;
}
int pdcp_netlink_dequeue_element(const protocol_ctxt_t* const ctxt_pP,
struct pdcp_netlink_element_s **data_ppP)
//-----------------------------------------------------------------------------
int
pdcp_netlink_dequeue_element(
const protocol_ctxt_t* const ctxt_pP,
struct pdcp_netlink_element_s** data_ppP
)
//-----------------------------------------------------------------------------
{
int ret = 0;
if (ctxt_pP->enb_flag) {
ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[ctxt_pP->enb_module_id], (void **)data_ppP);
if (ret != 0) {
LOG_D(PDCP,"[NETLINK]De-queueing packet for eNB instance %d\n", ctxt_pP->enb_module_id);
}
ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[ctxt_pP->module_id], (void**)data_ppP);
if (ret != 0) {
LOG_D(PDCP,"[NETLINK]De-queueing packet for eNB instance %d\n", ctxt_pP->module_id);
}
} else {
ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ctxt_pP->ue_module_id], (void **)data_ppP);
if (ret != 0) {
LOG_D(PDCP, "[NETLINK]De-queueing packet for UE instance %d\n", ctxt_pP->ue_module_id);
}
ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ctxt_pP->module_id], (void**)data_ppP);
if (ret != 0) {
LOG_D(PDCP, "[NETLINK]De-queueing packet for UE instance %d\n", ctxt_pP->module_id);
}
}
return ret;
}
//-----------------------------------------------------------------------------
static
void *pdcp_netlink_thread_fct(void *arg) {
void *pdcp_netlink_thread_fct(void *arg)
//-----------------------------------------------------------------------------
{
int len = 0;
struct pdcp_netlink_element_s *new_data_p = NULL;
uint8_t pdcp_thread_read_state ;
eNB_flag_t eNB_flag = 0;
module_id_t module_id = 0;
pdcp_thread_read_state = 0;
memset(nl_rx_buf, 0, NL_MAX_PAYLOAD);
LOG_I(PDCP, "[NETLINK_THREAD] binding to fd %d\n",nas_sock_fd);
MSC_START_USE();
while (1) {
len = recvmsg(nas_sock_fd, &nas_msg_rx, 0);
len = recvmsg(nas_sock_fd, &nas_msg_rx, 0);
if (len == 0) {
/* Other peer (kernel) has performed an orderly shutdown
*/
LOG_E(PDCP, "[NETLINK_THREAD] Kernel module has closed the netlink\n");
exit(EXIT_FAILURE);
} else if (len < 0) {
/* There was an error */
LOG_E(PDCP, "[NETLINK_THREAD] An error occured while reading netlink (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
/* Normal read.
* NOTE: netlink messages can be assembled to form a multipart message
*/
for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
NLMSG_OK(nas_nlh_rx, (unsigned int)len);
nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) {
start_meas(&ip_pdcp_stats_tmp);
/* There is no need to check for nlmsg_type because
* the header is not set in our drivers.
*/
if (pdcp_thread_read_state == 0) {
new_data_p = malloc(sizeof(struct pdcp_netlink_element_s));
if (len == 0) {
/* Other peer (kernel) has performed an orderly shutdown
*/
LOG_E(PDCP, "[NETLINK_THREAD] Kernel module has closed the netlink\n");
exit(EXIT_FAILURE);
} else if (len < 0) {
/* There was an error */
LOG_E(PDCP, "[NETLINK_THREAD] An error occured while reading netlink (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
/* Normal read.
* NOTE: netlink messages can be assembled to form a multipart message
*/
for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
NLMSG_OK(nas_nlh_rx, (unsigned int)len);
nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) {
start_meas(&ip_pdcp_stats_tmp);
if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
pdcp_thread_read_state = 1;
memcpy((void *)&new_data_p->pdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
LOG_I(PDCP, "[NETLINK_THREAD] RX pdcp_data_req_header_t inst %u, "
"rb_id %u data_size %d\n",
new_data_p->pdcp_read_header.inst,
new_data_p->pdcp_read_header.rb_id,
new_data_p->pdcp_read_header.data_size);
} else {
LOG_E(PDCP, "[NETLINK_THREAD] WRONG size %d should be sizeof "
"%d ((pdcp_data_req_header_t) + sizeof(struct nlmsghdr))\n",
nas_nlh_rx->nlmsg_len,
sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr));
}
} else {
pdcp_thread_read_state = 0;
/* There is no need to check for nlmsg_type because
* the header is not set in our drivers.
*/
if (pdcp_thread_read_state == 0) {
new_data_p = malloc(sizeof(struct pdcp_netlink_element_s));
if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
pdcp_thread_read_state = 1;
memcpy((void *)&new_data_p->pdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
LOG_I(PDCP, "[NETLINK_THREAD] RX pdcp_data_req_header_t inst %u, "
"rb_id %u data_size %d\n",
new_data_p->pdcp_read_header.inst,
new_data_p->pdcp_read_header.rb_id,
new_data_p->pdcp_read_header.data_size);
} else {
LOG_E(PDCP, "[NETLINK_THREAD] WRONG size %d should be sizeof "
"%d ((pdcp_data_req_header_t) + sizeof(struct nlmsghdr))\n",
nas_nlh_rx->nlmsg_len,
sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr));
}
} else {
pdcp_thread_read_state = 0;
#ifdef OAI_EMU
if (new_data_p->pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) {
new_data_p->pdcp_read_header.inst = new_data_p->pdcp_read_header.inst
- oai_emulation.info.nb_enb_local +
+ oai_emulation.info.first_ue_local;
eNB_flag = 0;
} else {
new_data_p->pdcp_read_header.inst = new_data_p->pdcp_read_header.inst
+ oai_emulation.info.first_enb_local;
eNB_flag = 1;
}
#else
new_data_p->pdcp_read_header.inst = 0;
#endif
new_data_p->data = malloc(sizeof(uint8_t) * new_data_p->pdcp_read_header.data_size);
/* Copy the data */
memcpy(new_data_p->data, NLMSG_DATA(nas_nlh_rx), new_data_p->pdcp_read_header.data_size);
if (eNB_flag) {
if (pdcp_netlink_nb_element_enb[new_data_p->pdcp_read_header.inst]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Inst %02x] We reached maximum number of elements in eNB pdcp queue (%d)\n",
new_data_p->pdcp_read_header.inst, pdcp_netlink_nb_element_enb);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for eNB instance %d\n", new_data_p->pdcp_read_header.inst);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_enb[new_data_p->pdcp_read_header.inst], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&eNB_pdcp_stats[new_data_p->pdcp_read_header.inst].pdcp_ip,&ip_pdcp_stats_tmp);
} else {
if (pdcp_netlink_nb_element_ue[new_data_p->pdcp_read_header.inst]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Inst %02x] We reached maximum number of elements in UE pdcp queue (%d)\n",
new_data_p->pdcp_read_header.inst, pdcp_netlink_nb_element_ue);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for UE instance %d\n", new_data_p->pdcp_read_header.inst);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_ue[new_data_p->pdcp_read_header.inst], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&UE_pdcp_stats[new_data_p->pdcp_read_header.inst].pdcp_ip,&ip_pdcp_stats_tmp);
}
}
// LG: new_data_p->pdcp_read_header.inst will contain in fact a module id
if (new_data_p->pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) {
module_id = new_data_p->pdcp_read_header.inst
- oai_emulation.info.nb_enb_local +
+ oai_emulation.info.first_ue_local;
eNB_flag = 0;
} else {
module_id = new_data_p->pdcp_read_header.inst
+ oai_emulation.info.first_enb_local;
eNB_flag = 1;
}
#else
module_id = 0;
#endif
new_data_p->data = malloc(sizeof(uint8_t) * new_data_p->pdcp_read_header.data_size);
/* Copy the data */
memcpy(new_data_p->data, NLMSG_DATA(nas_nlh_rx), new_data_p->pdcp_read_header.data_size);
if (eNB_flag) {
if (pdcp_netlink_nb_element_enb[module_id]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in eNB pdcp queue (%d)\n",
module_id, pdcp_netlink_nb_element_enb);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for eNB module id %d\n", module_id);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_enb[module_id], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&eNB_pdcp_stats[module_id].pdcp_ip,&ip_pdcp_stats_tmp);
} else {
if (pdcp_netlink_nb_element_ue[module_id]
> PDCP_QUEUE_NB_ELEMENTS) {
LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in UE pdcp queue (%d)\n",
module_id, pdcp_netlink_nb_element_ue);
}
LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for UE module id %d\n", module_id);
/* Enqueue the element in the right queue */
lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_ue[module_id], new_data_p);
stop_meas(&ip_pdcp_stats_tmp);
copy_meas(&UE_pdcp_stats[module_id].pdcp_ip,&ip_pdcp_stats_tmp);
}
}
}
}
}
return NULL;
}
#endif
+23 -16
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -53,12 +53,13 @@ uint8_t pdcp_get_dc_filed(unsigned char* pdu_buffer)
{
uint8_t dc = 0x00;
if (pdu_buffer == NULL)
if (pdu_buffer == NULL) {
return 0;
}
dc = (uint8_t)pdu_buffer[0] & 0xF0; // Reset D/C field
dc >>= 8;
dc >>= 8; // FIXME this is broken!!! returns 0 all the time
return dc;
}
@@ -73,8 +74,9 @@ uint16_t pdcp_get_sequence_number_of_pdu_with_long_sn(unsigned char* pdu_buffer)
{
uint16_t sequence_number = 0x00;
if (pdu_buffer == NULL)
if (pdu_buffer == NULL) {
return 0;
}
/*
* First octet carries the first 4 bits of SN (see 6.2.3)
@@ -98,8 +100,9 @@ uint16_t pdcp_get_sequence_number_of_pdu_with_long_sn(unsigned char* pdu_buffer)
*/
uint8_t pdcp_get_sequence_number_of_pdu_with_short_sn(unsigned char* pdu_buffer)
{
if (pdu_buffer == NULL)
if (pdu_buffer == NULL) {
return 0;
}
/*
* First octet carries all 7 bits of SN (see 6.2.4)
@@ -115,13 +118,14 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_short_sn(unsigned char* pdu_buffer)
*/
uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer)
{
if (pdu_buffer == NULL)
if (pdu_buffer == NULL) {
return 0;
}
/*
* First octet carries all 5 bits of SN (see 6.2.4)
*/
return (uint8_t)pdu_buffer[0] & 0x1F;
return (uint8_t)pdu_buffer[0] & 0x1F;
}
/*
* Fills the incoming buffer with the fields of the header for srb sn
@@ -130,17 +134,18 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer)
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \
pdcp_control_plane_data_pdu_header* pdu)
pdcp_control_plane_data_pdu_header* pdu)
{
if (pdu_buffer == NULL || pdu == NULL)
if (pdu_buffer == NULL || pdu == NULL) {
return FALSE;
}
/*
* Fill the Sequence Number field
*/
uint8_t sequence_number = pdu->sn;
pdu_buffer[0] = sequence_number & 0x1F; // 5bit sn
return TRUE;
}
@@ -151,10 +156,11 @@ boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \
pdcp_user_plane_data_pdu_header_with_long_sn* pdu)
pdcp_user_plane_data_pdu_header_with_long_sn* pdu)
{
if (pdu_buffer == NULL || pdu == NULL)
if (pdu_buffer == NULL || pdu == NULL) {
return FALSE;
}
/*
* Fill the Sequence Number field
@@ -183,10 +189,11 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char*
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \
uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu)
uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu)
{
if (pdu_buffer == NULL || pdu == NULL)
if (pdu_buffer == NULL || pdu == NULL) {
return FALSE;
}
/*
* Data or Control field and PDU type (already 0x00, noop)
@@ -199,7 +206,7 @@ boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_b
* Fill `First Missing PDU SN' field
*/
pdu_buffer[0] |= ((pdu->first_missing_sn >> 8) & 0xFF);
pdu_buffer[1] |= (pdu->first_missing_sn && 0xFF);
pdu_buffer[1] |= (pdu->first_missing_sn & 0xFF);
/*
* Append `bitmap'
+20 -18
View File
@@ -21,19 +21,22 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*
pdcp_primitives.h
-------------------
AUTHOR : Baris Demiray
COMPANY : EURECOM
EMAIL : Baris.Demiray@eurecom.fr
***************************************************************************/
***************************************************************************/
/*! \file LAYER2/PDCP_v10.1.0/pdcp_primitives.h
* \brief pdcp primitives
* \author Baris Demiray and Navid Nikaein
* \date 2009-2012
* \version 1.0
*/
/** \addtogroup _pdcp
* @{
*/
#ifndef PDCP_PRIMITIVES_H
#define PDCP_PRIMITIVES_H
@@ -41,9 +44,7 @@
* 3GPP TS 36.323 V10.1.0 (2011-03)
*/
/*
* Data or control (1-bit, see 6.3.7)
*/
/*! \brief Data or control (1-bit, see 6.3.7) */
#define PDCP_CONTROL_PDU_BIT_SET 0x00
#define PDCP_DATA_PDU_BIT_SET 0x01
@@ -61,7 +62,7 @@
#define PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE 4
typedef struct {
uint8_t sn; // PDCP sequence number will wrap around 2^5-1 so
// reserved field is unnecessary here
// reserved field is unnecessary here
uint8_t mac_i[PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE]; // Integration protection is not implemented (pad with 0)
} pdcp_control_plane_data_pdu_header;
@@ -146,13 +147,13 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_short_sn(unsigned char* pdu_buffer)
uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer);
/*
* Fills the incoming buffer with the fields of the header for SRB1
* Fills the incoming buffer with the fields of the header for SRB1
*
* @param pdu_buffer PDCP PDU buffer
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \
pdcp_control_plane_data_pdu_header* pdu);
pdcp_control_plane_data_pdu_header* pdu);
/*
* Fills the incoming buffer with the fields of the header for long SN (RLC UM and AM)
*
@@ -160,10 +161,10 @@ boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \
pdcp_user_plane_data_pdu_header_with_long_sn* pdu);
pdcp_user_plane_data_pdu_header_with_long_sn* pdu);
/*
* Fills the incoming status report header with given value of bitmap
* Fills the incoming status report header with given value of bitmap
* and 'first missing pdu' sequence number
*
* @param FMS First Missing PDCP SN
@@ -172,7 +173,7 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char*
* @return TRUE on success, FALSE otherwise
*/
boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \
uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu);
uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu);
int pdcp_netlink_dequeue_element(const protocol_ctxt_t* const ctxt_pP,
struct pdcp_netlink_element_s **data_ppP);
@@ -201,3 +202,4 @@ int pdcp_validate_security(const protocol_ctxt_t* const ctxt_pP,
#endif /* defined(ENABLE_SECURITY) */
#endif
/** @}*/
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -46,19 +46,20 @@ extern void pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size
extern void pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP);
extern void send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block * cprimitiveP);
extern void control_pdcp (struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_high(struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_high(struct pdcp_entity *pdcpP);
extern void pdcp_process_input_sdus_am (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void pdcp_process_output_sdus (struct pdcp_entity *pdcpP, mem_block * sduP, uint8_t rb_idP);
extern void pdcp_process_output_sdus_high (struct pdcp_entity *pdcpP, mem_block * sduP, uint16_t data_sizeP, uint16_t rb_idP);
extern void pdcp_process_output_sdus_high (struct pdcp_entity *pdcpP, mem_block * sduP, uint16_t data_sizeP, uint16_t rb_idP);
extern void pdcp_process_input_sdus_um (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern void init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP);
extern void *pdcp_tx (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block * sduP);
extern int reception_from_rohc_mt(void);
extern int reception_from_rohc_bs(void);
extern int reception_from_rohc_mt(void);
extern int reception_from_rohc_bs(void);
#else
extern BOOL pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP, uint8_t is_data_plane);
extern BOOL pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, uint8_t is_data_pdu);
extern BOOL pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer,
uint8_t is_data_pdu);
//extern BOOL pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP);
extern void send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block * cprimitiveP);
extern void control_pdcp (struct pdcp_entity *pdcpP);
+141 -132
View File
@@ -21,13 +21,13 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file pdcp_security.c
* \brief PDCP Security Methods
* \brief PDCP Security Methods
* \author ROUX Sebastie and Navid Nikaein
* \email openair_tech@eurecom.fr, navid.nikaein@eurecom.fr
* \date 2014
@@ -44,65 +44,70 @@
#include "LAYER2/MAC/extern.h"
#include "pdcp.h"
#include "msc.h"
#include "pdcp_primitives.h"
#if defined(ENABLE_SECURITY)
static
uint32_t pdcp_get_next_count_tx(pdcp_t *const pdcp_entity, const srb_flag_t srb_flagP, const uint16_t pdcp_sn);
uint32_t pdcp_get_next_count_tx(pdcp_t *const pdcp_pP, const srb_flag_t srb_flagP, const uint16_t pdcp_sn);
static
uint32_t pdcp_get_next_count_rx(pdcp_t *const pdcp_entity, const srb_flag_t srb_flagP, const uint16_t pdcp_sn);
uint32_t pdcp_get_next_count_rx(pdcp_t *const pdcp_pP, const srb_flag_t srb_flagP, const uint16_t pdcp_sn);
//-----------------------------------------------------------------------------
static
uint32_t pdcp_get_next_count_tx(
pdcp_t * const pdcp_entity,
const srb_flag_t srb_flagP,
const uint16_t pdcp_sn
)
pdcp_t * const pdcp_pP,
const srb_flag_t srb_flagP,
const uint16_t pdcp_sn
)
{
uint32_t count;
/* For TX COUNT = TX_HFN << length of SN | pdcp SN */
if (srb_flagP) {
/* 5 bits length SN */
count = ((pdcp_entity->tx_hfn << 5) | (pdcp_sn & 0x001F));
/* 5 bits length SN */
count = ((pdcp_pP->tx_hfn << 5) | (pdcp_sn & 0x001F));
} else {
if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
count = ((pdcp_entity->tx_hfn << 7) | (pdcp_sn & 0x07F));
} else { /*Default is the 12 bits length SN */
count = ((pdcp_entity->tx_hfn << 12) | (pdcp_sn & 0x0FFF));
}
if (pdcp_pP->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
count = ((pdcp_pP->tx_hfn << 7) | (pdcp_sn & 0x07F));
} else { /*Default is the 12 bits length SN */
count = ((pdcp_pP->tx_hfn << 12) | (pdcp_sn & 0x0FFF));
}
}
LOG_D(PDCP, "[OSA] TX COUNT = 0x%08x\n", count);
return count;
}
//-----------------------------------------------------------------------------
static
uint32_t pdcp_get_next_count_rx(
pdcp_t * const pdcp_entity,
const srb_flag_t srb_flagP,
const uint16_t pdcp_sn)
pdcp_t * const pdcp_pP,
const srb_flag_t srb_flagP,
const uint16_t pdcp_sn)
{
uint32_t count;
/* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */
if (srb_flagP) {
/* 5 bits length SN */
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 5) | (pdcp_sn & 0x001F));
/* 5 bits length SN */
count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 5) | (pdcp_sn & 0x001F));
} else {
if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
/* 7 bits length SN */
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F));
} else { // default
/* 12 bits length SN */
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 12) | (pdcp_sn & 0x0FFF));
}
if (pdcp_pP->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
/* 7 bits length SN */
count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F));
} else { // default
/* 12 bits length SN */
count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 12) | (pdcp_sn & 0x0FFF));
}
}
// reset the hfn offset
pdcp_entity->rx_hfn_offset =0;
pdcp_pP->rx_hfn_offset =0;
LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count);
return count;
}
@@ -110,139 +115,143 @@ uint32_t pdcp_get_next_count_rx(
//-----------------------------------------------------------------------------
int
pdcp_apply_security(
const protocol_ctxt_t* const ctxtP,
pdcp_t *const pdcp_entity,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const uint8_t pdcp_header_len,
const uint16_t current_sn,
uint8_t * const pdcp_pdu_buffer,
const uint16_t sdu_buffer_size
)
const protocol_ctxt_t* const ctxt_pP,
pdcp_t *const pdcp_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const uint8_t pdcp_header_len,
const uint16_t current_sn,
uint8_t * const pdcp_pdu_buffer,
const uint16_t sdu_buffer_size
)
{
uint8_t *buffer_encrypted = NULL;
stream_cipher_t encrypt_params;
uint8_t *buffer_encrypted = NULL;
stream_cipher_t encrypt_params;
DevAssert(pdcp_entity != NULL);
DevAssert(pdcp_pdu_buffer != NULL);
DevCheck(rb_id < NB_RB_MAX && rb_id >= 0, rb_id, NB_RB_MAX, 0);
DevAssert(pdcp_pP != NULL);
DevAssert(pdcp_pdu_buffer != NULL);
DevCheck(rb_id < NB_RB_MAX && rb_id >= 0, rb_id, NB_RB_MAX, 0);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_IN);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_IN);
encrypt_params.direction = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
encrypt_params.bearer = rb_id - 1;
encrypt_params.count = pdcp_get_next_count_tx(pdcp_entity, srb_flagP, current_sn);
encrypt_params.key_length = 16;
encrypt_params.direction = (pdcp_pP->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
encrypt_params.bearer = rb_id - 1;
encrypt_params.count = pdcp_get_next_count_tx(pdcp_pP, srb_flagP, current_sn);
encrypt_params.key_length = 16;
if (srb_flagP) {
/* SRBs */
uint8_t *mac_i;
if (srb_flagP) {
/* SRBs */
uint8_t *mac_i;
LOG_D(PDCP, "[OSA][RB %d] %s Applying control-plane security %d \n",
rb_id, (pdcp_entity->is_ue != 0) ? "UE -> eNB" : "eNB -> UE", pdcp_entity->integrityProtAlgorithm);
LOG_D(PDCP, "[OSA][RB %d] %s Applying control-plane security %d \n",
rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE", pdcp_pP->integrityProtAlgorithm);
encrypt_params.message = pdcp_pdu_buffer;
encrypt_params.blength = (pdcp_header_len + sdu_buffer_size) << 3;
encrypt_params.key = pdcp_entity->kRRCint + 16; // + 128;
encrypt_params.message = pdcp_pdu_buffer;
encrypt_params.blength = (pdcp_header_len + sdu_buffer_size) << 3;
encrypt_params.key = pdcp_pP->kRRCint + 16; // + 128;
mac_i = &pdcp_pdu_buffer[pdcp_header_len + sdu_buffer_size];
mac_i = &pdcp_pdu_buffer[pdcp_header_len + sdu_buffer_size];
/* Both header and data parts are integrity protected for
* control-plane PDUs */
stream_compute_integrity(pdcp_entity->integrityProtAlgorithm,
&encrypt_params,
mac_i);
/* Both header and data parts are integrity protected for
* control-plane PDUs */
stream_compute_integrity(pdcp_pP->integrityProtAlgorithm,
&encrypt_params,
mac_i);
encrypt_params.key = pdcp_entity->kRRCenc; // + 128 // bit key
} else {
LOG_D(PDCP, "[OSA][RB %d] %s Applying user-plane security\n",
rb_id, (pdcp_entity->is_ue != 0) ? "UE -> eNB" : "eNB -> UE");
encrypt_params.key = pdcp_pP->kRRCenc; // + 128 // bit key
} else {
LOG_D(PDCP, "[OSA][RB %d] %s Applying user-plane security\n",
rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE");
encrypt_params.key = pdcp_entity->kUPenc;// + 128;
}
encrypt_params.key = pdcp_pP->kUPenc;// + 128;
}
encrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
encrypt_params.blength = sdu_buffer_size << 3;
encrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
encrypt_params.blength = sdu_buffer_size << 3;
buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len];
buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len];
/* Apply ciphering if any requested */
stream_encrypt(pdcp_entity->cipheringAlgorithm,
&encrypt_params,
&buffer_encrypted);
/* Apply ciphering if any requested */
stream_encrypt(pdcp_pP->cipheringAlgorithm,
&encrypt_params,
&buffer_encrypted);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT);
return 0;
return 0;
}
//-----------------------------------------------------------------------------
int
pdcp_validate_security(
const protocol_ctxt_t* const ctxtP,
pdcp_t * const pdcp_entity,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const uint8_t pdcp_header_len,
const uint16_t current_sn,
uint8_t *const pdcp_pdu_buffer,
const uint16_t sdu_buffer_size
)
const protocol_ctxt_t* const ctxt_pP,
pdcp_t * const pdcp_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const uint8_t pdcp_header_len,
const uint16_t current_sn,
uint8_t *const pdcp_pdu_buffer,
const uint16_t sdu_buffer_size
)
{
uint8_t *buffer_decrypted = NULL;
stream_cipher_t decrypt_params;
uint8_t *buffer_decrypted = NULL;
stream_cipher_t decrypt_params;
DevAssert(pdcp_entity != NULL);
DevAssert(pdcp_pP != NULL);
DevAssert(pdcp_pdu_buffer != NULL);
DevCheck(rb_id < NB_RB_MAX && rb_id >= 0, rb_id, NB_RB_MAX, 0);
DevAssert(pdcp_pdu_buffer != NULL);
DevCheck(rb_id < NB_RB_MAX && rb_id >= 0, rb_id, NB_RB_MAX, 0);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_IN);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_IN);
buffer_decrypted = (uint8_t*)&pdcp_pdu_buffer[pdcp_header_len];
buffer_decrypted = (uint8_t*)&pdcp_pdu_buffer[pdcp_header_len];
decrypt_params.direction = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_DOWNLINK : SECU_DIRECTION_UPLINK ;
decrypt_params.bearer = rb_id - 1;
decrypt_params.count = pdcp_get_next_count_rx(pdcp_entity, srb_flagP, current_sn);
decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3;
decrypt_params.key_length = 16;
decrypt_params.direction = (pdcp_pP->is_ue == 1) ? SECU_DIRECTION_DOWNLINK : SECU_DIRECTION_UPLINK ;
decrypt_params.bearer = rb_id - 1;
decrypt_params.count = pdcp_get_next_count_rx(pdcp_pP, srb_flagP, current_sn);
decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3;
decrypt_params.key_length = 16;
if (srb_flagP) {
LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n",
rb_id, (pdcp_entity->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
decrypt_params.key = pdcp_entity->kRRCenc;// + 128;
} else {
LOG_D(PDCP, "[OSA][RB %d] %s Validating user-plane security\n",
rb_id, (pdcp_entity->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
decrypt_params.key = pdcp_entity->kUPenc;// + 128;
if (srb_flagP) {
LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n",
rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
decrypt_params.key = pdcp_pP->kRRCenc;// + 128;
} else {
LOG_D(PDCP, "[OSA][RB %d] %s Validating user-plane security\n",
rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
decrypt_params.key = pdcp_pP->kUPenc;// + 128;
}
/* Uncipher the block */
stream_decrypt(pdcp_pP->cipheringAlgorithm,
&decrypt_params,
&buffer_decrypted);
if (srb_flagP) {
/* Now check the integrity of the complete PDU */
decrypt_params.message = pdcp_pdu_buffer;
decrypt_params.blength = sdu_buffer_size << 3;
decrypt_params.key = pdcp_pP->kRRCint + 16;// 128;
if (stream_check_integrity(pdcp_pP->integrityProtAlgorithm,
&decrypt_params,
&pdcp_pdu_buffer[sdu_buffer_size]) != 0) {
MSC_LOG_EVENT(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
" Security: failed MAC-I Algo %X UE %"PRIx16" ",
pdcp_pP->integrityProtAlgorithm,
ctxt_pP->rnti);
LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I of incoming PDU\n",
rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
return -1;
}
}
/* Uncipher the block */
stream_decrypt(pdcp_entity->cipheringAlgorithm,
&decrypt_params,
&buffer_decrypted);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
if (srb_flagP) {
/* Now check the integrity of the complete PDU */
decrypt_params.message = pdcp_pdu_buffer;
decrypt_params.blength = sdu_buffer_size << 3;
decrypt_params.key = pdcp_entity->kRRCint + 16;// 128;
if (stream_check_integrity(pdcp_entity->integrityProtAlgorithm,
&decrypt_params,
&pdcp_pdu_buffer[sdu_buffer_size]) != 0)
{
LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I of incoming PDU\n",
rb_id, (pdcp_entity->is_ue != 0) ? "UE" : "eNB");
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
return -1;
}
}
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
return 0;
return 0;
}
#endif /* ENABLE_SECURITY */
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -45,8 +45,9 @@
*/
boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity)
{
if (pdcp_entity == NULL)
if (pdcp_entity == NULL) {
return FALSE;
}
/* Sequence number state variables */
@@ -67,8 +68,9 @@ boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity)
boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity)
{
if (pdcp_entity == NULL)
if (pdcp_entity == NULL) {
return FALSE;
}
// Check if the size of SN is valid (see 3GPP TS 36.323 v10.1.0 item 6.3.2)
if (pdcp_entity->seq_num_size != 5 && pdcp_entity->seq_num_size != 7 && pdcp_entity->seq_num_size != 12) {
@@ -84,8 +86,9 @@ boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity)
*/
boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size)
{
if (seq_num >= 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size))
if (seq_num >= 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size)) {
return TRUE;
}
return FALSE;
}
@@ -101,8 +104,9 @@ uint16_t pdcp_calculate_max_seq_num_for_given_size(uint8_t seq_num_size)
uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity)
{
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE)
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) {
return -1;
}
// Sequence number should be incremented after it is assigned for a PDU
uint16_t pdcp_seq_num = pdcp_entity->next_pdcp_tx_sn;
@@ -124,8 +128,9 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity)
boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity)
{
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE)
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) {
return FALSE;
}
/*
* Update sequence numbering state and Hyper Frame Number if SN has already reached
@@ -134,6 +139,7 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity)
#if 0
LOG_D(PDCP, "Advancing RX window...\n");
#endif
if (pdcp_entity->next_pdcp_rx_sn == pdcp_calculate_max_seq_num_for_given_size(pdcp_entity->seq_num_size)) {
pdcp_entity->next_pdcp_rx_sn = 0;
pdcp_entity->rx_hfn++;
@@ -149,15 +155,18 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity)
* @return 1 if SN is okay, 0 otherwise
* XXX Reordering window should also be handled here
*/
boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP) {
boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP)
{
uint16_t reordering_window = 0;
#if 0
LOG_D(PDCP, "Incoming RX Sequence number is %04d\n", seq_num);
#endif
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE || pdcp_is_seq_num_valid(seq_num, pdcp_entity->seq_num_size) == FALSE)
if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE || pdcp_is_seq_num_valid(seq_num, pdcp_entity->seq_num_size) == FALSE) {
return FALSE;
}
/*
* Mark received sequence numbers to keep track of missing ones
@@ -174,102 +183,108 @@ boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_
/*
* RX Procedures for SRB and DRBs as described in sec 5.1.2 of 36.323
*/
if (srb_flagP) { // SRB
if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
// decipher and verify the integrity of the PDU (if applicable) using COUNT based on RX_HFN + 1 and the received PDCP SN
// decipher and verify the integrity of the PDU (if applicable) using COUNT based on RX_HFN + 1 and the received PDCP SN
pdcp_entity->rx_hfn++;
pdcp_entity->rx_hfn_offset = 0;
} else{
} else {
// decipher and verify the integrity of the PDU (if applicable) using COUNT based using COUNT based on RX_HFN and the received PDCP SN
pdcp_entity->rx_hfn_offset = 0;
}
// Assume that integrity verification is applicable and the integrity verification is passed successfully;
// Assume that integrity verification is applicable and the integrity verification is passed successfully;
// or assume that integrity verification is not applicable:
// same the old next_pdcp_rx_sn to revert otherwise
pdcp_entity->next_pdcp_rx_sn_before_integrity = pdcp_entity->next_pdcp_rx_sn;
#if 0
if (seq_num != pdcp_entity->next_pdcp_rx_sn)
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
if (seq_num != pdcp_entity->next_pdcp_rx_sn) {
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
}
#endif
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
pdcp_entity->next_pdcp_rx_sn = seq_num;
pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN:
} else { // DRB
if (pdcp_entity->seq_num_size == PDCP_SN_7BIT)
if (pdcp_entity->seq_num_size == PDCP_SN_7BIT) {
reordering_window = REORDERING_WINDOW_SN_7BIT;
else
} else {
reordering_window = REORDERING_WINDOW_SN_12BIT;
}
switch (pdcp_entity->rlc_mode) {
case RLC_MODE_AM:
if ((seq_num - pdcp_entity->last_submitted_pdcp_rx_sn > reordering_window) ||
((0 <= pdcp_entity->last_submitted_pdcp_rx_sn - seq_num) &&
(pdcp_entity->last_submitted_pdcp_rx_sn - seq_num < reordering_window) )) {
if (seq_num > pdcp_entity->next_pdcp_rx_sn) {
/*
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN - 1 and the received PDCP SN;
*/
pdcp_entity->rx_hfn_offset = -1;
} else {
/*
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN and the received PDCP SN;
*/
pdcp_entity->rx_hfn_offset = 0;
}
// discard this PDCP SDU;
LOG_W(PDCP, "Out of the reordering window (Incoming SN:%d, Expected SN:%d): discard this PDCP SDU\n",
seq_num, pdcp_entity->next_pdcp_rx_sn);
return FALSE;
case RLC_MODE_AM:
if ((seq_num - pdcp_entity->last_submitted_pdcp_rx_sn > reordering_window) ||
((0 <= pdcp_entity->last_submitted_pdcp_rx_sn - seq_num) &&
(pdcp_entity->last_submitted_pdcp_rx_sn - seq_num < reordering_window) )) {
if (seq_num > pdcp_entity->next_pdcp_rx_sn) {
/*
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN - 1 and the received PDCP SN;
*/
pdcp_entity->rx_hfn_offset = -1;
} else {
/*
* decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN and the received PDCP SN;
*/
pdcp_entity->rx_hfn_offset = 0;
}
// discard this PDCP SDU;
LOG_W(PDCP, "Out of the reordering window (Incoming SN:%d, Expected SN:%d): discard this PDCP SDU\n",
seq_num, pdcp_entity->next_pdcp_rx_sn);
return FALSE;
} else if (pdcp_entity->next_pdcp_rx_sn - seq_num > reordering_window) {
pdcp_entity->rx_hfn++;
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
pdcp_entity->next_pdcp_rx_sn++;
}
else if (seq_num - pdcp_entity->next_pdcp_rx_sn >= reordering_window ){
// use COUNT based on RX_HFN – 1 and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = -1;
}
else if (seq_num >= pdcp_entity->next_pdcp_rx_sn ) {
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
pdcp_entity->next_pdcp_rx_sn = seq_num;
pdcp_advance_rx_window(pdcp_entity); // + 1, anc check if it is larger than Maximum_PDCP_SN:
pdcp_entity->rx_hfn++;
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
pdcp_entity->next_pdcp_rx_sn++;
} else if (seq_num - pdcp_entity->next_pdcp_rx_sn >= reordering_window ) {
// use COUNT based on RX_HFN – 1 and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = -1;
} else if (seq_num >= pdcp_entity->next_pdcp_rx_sn ) {
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
pdcp_entity->next_pdcp_rx_sn = seq_num;
pdcp_advance_rx_window(pdcp_entity); // + 1, anc check if it is larger than Maximum_PDCP_SN:
#if 0
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
#endif
} else if (seq_num < pdcp_entity->next_pdcp_rx_sn){
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
} else if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
pdcp_entity->rx_hfn_offset = 0;
}
break;
case RLC_MODE_UM :
if (seq_num < pdcp_entity->next_pdcp_rx_sn)
pdcp_entity->rx_hfn++;
if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
pdcp_entity->rx_hfn++;
}
// decipher the PDCP Data PDU using COUNT based on RX_HFN and the received PDCP SN as specified in the subclause 5.6;
//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
pdcp_entity->next_pdcp_rx_sn = seq_num;
pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN:
break;
case RLC_MODE_TM :
case RLC_MODE_TM :
default:
LOG_W(PDCP,"RLC mode %d not supported\n",pdcp_entity->rlc_mode);
return FALSE;
}
}
/*
/*
if (seq_num == pdcp_entity->next_pdcp_rx_sn) {
LOG_I(PDCP, "Next expected SN (%d) arrived, advancing RX window\n", seq_num);
@@ -277,7 +292,7 @@ boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_
} else {
LOG_E(PDCP, "Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \
seq_num, pdcp_entity->next_pdcp_rx_sn);
// Update first missing PDU (used in PDCP Control PDU for PDCP status report, see 6.2.6)
if (pdcp_entity->first_missing_pdu != -1)
@@ -285,7 +300,7 @@ boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_
return FALSE;
}
*/
*/
return TRUE;
}
@@ -293,7 +308,7 @@ boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entit
{
/*
* Incoming sequence number and PDCP entity were already
* validated in pdcp_is_rx_seq_number_valid() so we don't
* validated in pdcp_is_rx_seq_number_valid() so we don't
* check here
*/
@@ -307,7 +322,7 @@ boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entit
#if 0
LOG_D(PDCP, "Marking %d. bit of %d. octet of status bitmap\n", (seq_num % 8) + 1, octet_index);
#endif
util_mark_nth_bit_of_octet(&pdcp_entity->missing_pdu_bitmap[octet_index], seq_num % 8);
util_mark_nth_bit_of_octet(&pdcp_entity->missing_pdu_bitmap[octet_index], seq_num % 8);
#if 0
util_print_binary_representation((uint8_t*)"Current state of relevant octet: ", pdcp_entity->missing_pdu_bitmap[octet_index]);
#endif
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+49 -41
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -44,6 +44,7 @@
#include "PHY/extern.h" //for PHY_vars
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "msc.h"
#define OPENAIR_THREAD_STACK_SIZE 8192
#define OPENAIR_THREAD_PRIORITY 255
@@ -59,51 +60,54 @@ int pdcp_instance_cnt;
static void *pdcp_thread_main(void* param);
static void *pdcp_thread_main(void* param) {
static void *pdcp_thread_main(void* param)
{
uint8_t eNB_flag = !UE_flag;
LOG_I(PDCP,"This is pdcp_thread eNB_flag = %d\n",eNB_flag);
MSC_START_USE();
while (!oai_exit) {
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error locking mutex.\n");
}
else {
while (pdcp_instance_cnt < 0) {
pthread_cond_wait(&pdcp_cond,&pdcp_mutex);
}
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error unlocking mutex.\n");
}
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error locking mutex.\n");
} else {
while (pdcp_instance_cnt < 0) {
pthread_cond_wait(&pdcp_cond,&pdcp_mutex);
}
if (oai_exit) break;
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error unlocking mutex.\n");
}
}
if (eNB_flag) {
pdcp_run(PHY_vars_eNB_g[0]->frame, eNB_flag, PHY_vars_eNB_g[0]->Mod_id, 0);
LOG_D(PDCP,"Calling pdcp_run (eNB) for frame %d\n",PHY_vars_eNB_g[0]->frame);
}
else {
pdcp_run(PHY_vars_UE_g[0]->frame, eNB_flag, 0, PHY_vars_UE_g[0]->Mod_id);
LOG_D(PDCP,"Calling pdcp_run (UE) for frame %d\n",PHY_vars_UE_g[0]->frame);
}
if (oai_exit) break;
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error locking mutex.\n");
}
else {
pdcp_instance_cnt--;
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error unlocking mutex.\n");
}
if (eNB_flag) {
pdcp_run(PHY_vars_eNB_g[0]->frame, eNB_flag, PHY_vars_eNB_g[0]->Mod_id, 0);
LOG_D(PDCP,"Calling pdcp_run (eNB) for frame %d\n",PHY_vars_eNB_g[0]->frame);
} else {
pdcp_run(PHY_vars_UE_g[0]->frame, eNB_flag, 0, PHY_vars_UE_g[0]->Mod_id);
LOG_D(PDCP,"Calling pdcp_run (UE) for frame %d\n",PHY_vars_UE_g[0]->frame);
}
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error locking mutex.\n");
} else {
pdcp_instance_cnt--;
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
LOG_E(PDCP,"Error unlocking mutex.\n");
}
}
}
return(NULL);
}
int init_pdcp_thread(void) {
int init_pdcp_thread(void)
{
int error_code;
struct sched_param p;
@@ -123,31 +127,35 @@ int init_pdcp_thread(void) {
pdcp_instance_cnt = -1;
LOG_I(PDCP,"Allocating PDCP thread\n");
error_code = pthread_create(&pdcp_thread,
&pdcp_thread_attr,
pdcp_thread_main,
(void*)NULL);
&pdcp_thread_attr,
pdcp_thread_main,
(void*)NULL);
if (error_code!= 0) {
LOG_I(PDCP,"Could not allocate PDCP thread, error %d\n",error_code);
return(error_code);
}
else {
LOG_I(PDCP,"Allocate PDCP thread successful\n");
LOG_I(PDCP,"Could not allocate PDCP thread, error %d\n",error_code);
return(error_code);
} else {
LOG_I(PDCP,"Allocate PDCP thread successful\n");
pthread_setname_np( pdcp_thread, "PDCP" );
}
return(0);
}
void cleanup_pdcp_thread(void) {
void cleanup_pdcp_thread(void)
{
void *status_p = NULL;
LOG_I(PDCP,"Scheduling PDCP thread to exit\n");
pdcp_instance_cnt = 0;
if (pthread_cond_signal(&pdcp_cond) != 0)
if (pthread_cond_signal(&pdcp_cond) != 0) {
LOG_I(PDCP,"ERROR pthread_cond_signal\n");
else
} else {
LOG_I(PDCP,"Signalled PDCP thread to exit\n");
}
pthread_join(pdcp_thread,&status_p);
LOG_I(PDCP,"PDCP thread exited\n");
+15 -6
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -58,26 +58,31 @@ void util_print_hex_octets(comp_name_t component, unsigned char* data, unsigned
LOG_T(component, " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
LOG_T(component, "-----+-------------------------------------------------|\n");
LOG_T(component, " 000 |");
for (octet_index = 0; octet_index < size; ++octet_index) {
/*
* Print every single octet in hexadecimal form
*/
LOG_T(component, "%02x.", data[octet_index]);
/*
* Align newline and pipes according to the octets in groups of 2
*/
if (octet_index != 0 && (octet_index + 1) % 16 == 0) {
LOG_T(component, " |\n");
LOG_T(component, " %03d |", octet_index);
}
}
}
/*
* Append enough spaces and put final pipe
*/
unsigned char index;
for (index = octet_index; index < 16; ++index)
for (index = octet_index; index < 16; ++index) {
LOG_T(component, " ");
}
LOG_T(component, " \n");
}
@@ -87,19 +92,22 @@ void util_flush_hex_octets(comp_name_t component, unsigned char* data, unsigned
LOG_W(component, "Incoming buffer is NULL! Ignoring...\n");
return;
}
printf("[PDCP]");
unsigned long octet_index = 0;
for (octet_index = 0; octet_index < size; ++octet_index) {
//LOG_T(component, "%02x.", data[octet_index]);
printf("%02x.", data[octet_index]);
//LOG_T(component, "%02x.", data[octet_index]);
printf("%02x.", data[octet_index]);
}
//LOG_T(component, " \n");
printf(" \n");
}
/*
* Prints binary representation of given octet prepending
* Prints binary representation of given octet prepending
* passed log message
*
* @param Octet as an unsigned character
@@ -121,6 +129,7 @@ void util_print_binary_representation(unsigned char* message, uint8_t octet)
mask /= 2;
}
LOG_T(PDCP, "\n");
}
+2 -2
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -61,7 +61,7 @@ void util_print_hex_octets(comp_name_t component, unsigned char* data, unsigned
void util_flush_hex_octets(comp_name_t component, unsigned char* data, unsigned long size);
/*
* Prints binary representation of given octet prepending
* Prints binary representation of given octet prepending
* passed log message
*
* @param Octet as an unsigned character
-586
View File
@@ -1,586 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
#include "platform_constants.h"
//-----------------------------------------------------------------------------
#include "rlc_am_entity.h"
#include "rlc_am_mux_proto_extern.h"
#include "rlc_am_segment_proto_extern.h"
#include "rlc_am_receiver_proto_extern.h"
#include "rlc_am_demux_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "rlc_am_status_proto_extern.h"
#include "rlc_am_errno.h"
#include "umts_timer_proto_extern.h"
#include "rlc_am_discard_rx_proto_extern.h"
#include "rlc_am_discard_tx_proto_extern.h"
#include "rlc_am_discard_notif_proto_extern.h"
#include "mac_primitives.h"
#include "rlc_primitives.h"
#include "rlc_am_control_primitives_proto_extern.h"
#include "rlc_am_util_proto_extern.h"
#include "list.h"
#include "LAYER2/MAC/extern.h"
//#define DEBUG_RLC_AM_DATA_REQUEST
//#define DEBUG_RLC_AM_TX
//#define DEBUG_RLC_AM_RX
//#define DEBUG_RLC_AM_BO
//-----------------------------------------------------------------------------
void display_protocol_vars_rlc_am (struct rlc_am_entity *rlcP);
uint32_t rlc_am_get_buffer_occupancy_in_pdus_for_ch1 (struct rlc_am_entity *rlcP);
uint32_t rlc_am_get_buffer_occupancy_in_pdus_for_ch2 (struct rlc_am_entity *rlcP);
void *rlc_am_tx (void *argP);
void rlc_am_rx (void *argP, struct mac_data_ind data_indP);
//-----------------------------------------------------------------------------
uint32_t
rlc_am_get_buffer_occupancy_in_bytes_ch1 (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
uint32_t sum = 0;
if (rlcP->buffer_occupancy > 0) {
sum += (rlcP->pdus_to_mac_layer_ch1.nb_elements * rlcP->pdu_size);
sum += (rlcP->buffer_occupancy_retransmission_buffer * rlcP->pdu_size);
sum += rlcP->control.nb_elements * rlcP->pdu_size; // TEST LG + HA 23/10/2008
sum += rlcP->buffer_occupancy; // approximation because of headers of pdus
} else {
if ((rlcP->li_one_byte_short_to_add_in_next_pdu) ||
(rlcP->li_exactly_filled_to_add_in_next_pdu)) {
// WARNING LG WE ASSUME TRANSPORT BLOCKS ARE < 125 bytes
sum = rlcP->pdu_size; // 4 bytes; // so this is the exact size of the next TB to be sent (SN + 2LIs)
}
}
#ifdef DEBUG_RLC_AM_BO
msg ("[RLC_AM][RB %d] DTCH BO: %d bytes \n", rlcP->rb_id,sum);
#endif
return sum;
}
//-----------------------------------------------------------------------------
uint32_t
rlc_am_get_buffer_occupancy_in_bytes_ch2 (struct rlc_am_entity * rlcP)
{
//-----------------------------------------------------------------------------
#ifdef DEBUG_RLC_AM_BO
msg ("[RLC_AM][RB %d] DCCH BO: CONTROL %d DCCH %d\n", rlcP->rb_id, rlcP->control.nb_elements * rlcP->pdu_size, rlcP->pdus_to_mac_layer_ch2.nb_elements * rlcP->pdu_size);
#endif
return rlcP->control.nb_elements * rlcP->pdu_size + rlcP->pdus_to_mac_layer_ch2.nb_elements * rlcP->pdu_size;
}
//-----------------------------------------------------------------------------
uint32_t
rlc_am_get_buffer_occupancy_in_pdus_ch1 (struct rlc_am_entity * rlcP)
{
//-----------------------------------------------------------------------------
uint32_t sum = 0;
sum += rlcP->pdus_to_mac_layer_ch1.nb_elements;
sum += rlcP->buffer_occupancy_retransmission_buffer;
sum += rlcP->control.nb_elements; // TEST LG + HA 23/10/2008
sum += (rlcP->buffer_occupancy / (rlcP->pdu_size - 2)); // minus 2 = size min for pdu header
#ifdef DEBUG_RLC_AM_BO
msg ("[RLC_AM][RB %d] BO : CH1 %d blocks \n", rlcP->rb_id, rlcP->pdus_to_mac_layer_ch1.nb_elements);
msg ("[RLC_AM][RB %d] BO : RETRANS BUFFER %d blocks \n", rlcP->rb_id, rlcP->buffer_occupancy_retransmission_buffer);
msg ("[RLC_AM][RB %d] BO : BUFFER SDU %d blocks \n", rlcP->rb_id, rlcP->buffer_occupancy / (rlcP->pdu_size - 2));
#endif
return sum;
}
//-----------------------------------------------------------------------------
uint32_t
rlc_am_get_buffer_occupancy_in_pdus_ch2 (struct rlc_am_entity * rlcP)
{
//-----------------------------------------------------------------------------
#ifdef DEBUG_RLC_AM_BO
msg ("[RLC_AM][RB %d] BO : CH2 CONTROL %d DCCH %d\n", rlcP->rb_id, rlcP->control.nb_elements, rlcP->pdus_to_mac_layer_ch2.nb_elements);
#endif
return rlcP->control.nb_elements + rlcP->pdus_to_mac_layer_ch2.nb_elements;
}
//-----------------------------------------------------------------------------
void
rlc_am_get_pdus (void *argP, uint8_t traffic_typeP)
{
//-----------------------------------------------------------------------------
struct rlc_am_entity *rlc = (struct rlc_am_entity *) argP;
switch (rlc->protocol_state) {
case RLC_NULL_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the NULL state the RLC entity does not exist and therefore it is not possible to transfer any data through it.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating establishment, the RLC entity:
// - is created; and
// - enters the DATA_TRANSFER_READY state.
break;
case RLC_DATA_TRANSFER_READY_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the DATA_TRANSFER_READY state, acknowledged mode data can be exchanged between the entities according to subclause 11.3.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon detection of an initiating condition for the RLC reset procedure described in subclause 11.4.2, the RLC entity:
// - initiates the RLC reset procedure (see subclause 11.4); and
// - enters the RESET_PENDING state.
// Upon reception of a RESET PDU, the RLC entity responds according to subclause 11.4.3.
// Upon reception of a RESET ACK PDU, the RLC entity takes no action.
// Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity is suspended and enters the LOCAL_SUSPEND state.
// SEND DATA TO MAC
umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds);
if ((rlc->send_status_pdu_requested)) {
// may be timer status prohibit
if (rlc_am_send_status (rlc) > 0) {
rlc->send_status_pdu_requested = 0;
}
} else if ((rlc->timer_status_periodic) && ((Mac_rlc_xface->frame % (rlc->timer_status_periodic / 10)) == 0) && (rlc->last_tx_status_frame != Mac_rlc_xface->frame)) {
// may be MAC can poll RLC more than once in a time frame
//msg ("[RLC_AM][RB %d] SEND STATUS PERIODIC frame %d\n", rlc->rb_id, Mac_rlc_xface->frame);
if (rlc_am_send_status (rlc) > 0) {
rlc->send_status_pdu_requested = 0;
}
rlc->last_tx_status_frame = Mac_rlc_xface->frame;
}
#ifdef NODE_MT
rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
#else
rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
#endif
break;
case RLC_RESET_PENDING_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the RESET_PENDING state the entity waits for a response from its peer entity and no data can be exchanged between the entities.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity:
// - acts according to subclause 11.4.4; and
// - enters the DATA_TRANSFER_READY state.
// Upon reception of a RESET ACK PDU with a different RSN value as in the corresponding RESET PDU, the RLC entity:
// - discards the RESET ACK PDU (see subclause 11.4.4); and
// - stays in the RESET_PENDING state.
// Upon reception of a RESET PDU, the RLC entity:
// - responds according to subclause 11.4.3; and
// - stays in the RESET_PENDING state.
// Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity:
// - enters the RESET_AND_SUSPEND state.
umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds);
#ifdef NODE_MT
rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED);
#else
rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED);
#endif
break;
case RLC_RESET_AND_SUSPEND_STATE:
// In the RESET_ AND_SUSPEND state, the entity waits for a response from its peer entity or a primitive (CRLC-RESUME-Req) from its upper layer and no data can be exchanged between the entities.
// Upon reception of CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity:
// - acts according to subclause 11.4.4; and
// - enters the LOCAL_SUSPEND state.
// Upon reception of CRLC-RESUME-Req from upper layer in this state, the RLC entity:
// - is resumed, i.e. releases the suspend constraint; and
// - enters the RESET_PENDING state.
#ifdef NODE_MT
rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED);
#else
rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED);
#endif
break;
case RLC_LOCAL_SUSPEND_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the LOCAL_SUSPEND state, the RLC entity is suspended, i.e. it does not send AMD PDUs with SN greater than or equal to certain specified value (see subclause 9.7.5).
// Upon reception of CRLC-RESUME-Req from upper layers in this state, the RLC entity:
// - resumes the data transmission; and
// - enters the DATA_TRANSFER_READY state.
// Upon reception of CRLC-CONFIG-Req from upper layers indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon detection of an initiating condition for RLC reset procedure described in subclause 11.4.2, the RLC entity:
// - initiates the RLC reset procedure (see subclause 11.4); and
// - enters the RESET_AND_SUSPEND state.
// TO DO TAKE CARE OF SN : THE IMPLEMENTATION OF THIS FUNCTIONNALITY IS NOT CRITICAL
if ((rlc->send_status_pdu_requested)) {
rlc_am_send_status (rlc);
rlc->send_status_pdu_requested = 0;
}
#ifdef NODE_MT
rlc_am_mux_ue (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS);
#else
rlc_am_mux_rg (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS);
#endif
break;
default:
msg ("[RLC_AM][RB %d] MAC_DATA_REQ UNKNOWN PROTOCOL STATE 0x%02X\n", rlc->rb_id, rlc->protocol_state);
}
}
//-----------------------------------------------------------------------------
void
rlc_am_rx (void *argP, struct mac_data_ind data_indP)
{
//-----------------------------------------------------------------------------
struct rlc_am_entity *rlc = (struct rlc_am_entity *) argP;
#ifdef DEBUG_RLC_AM_RX
msg("[RLC][AM] In rlc_am_rx\n");
#endif
switch (rlc->protocol_state) {
case RLC_NULL_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the NULL state the RLC entity does not exist and therefore it is not possible to transfer any data through it.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating establishment, the RLC entity:
// - is created; and
// - enters the DATA_TRANSFER_READY state.
msg ("[RLC_AM %p] ERROR MAC_DATA_IND IN RLC_NULL_STATE\n", argP);
list_free (&data_indP.data);
break;
case RLC_DATA_TRANSFER_READY_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the DATA_TRANSFER_READY state, acknowledged mode data can be exchanged between the entities according to subclause 11.3.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon detection of an initiating condition for the RLC reset procedure described in subclause 11.4.2, the RLC entity:
// - initiates the RLC reset procedure (see subclause 11.4); and
// - enters the RESET_PENDING state.
// Upon reception of a RESET PDU, the RLC entity responds according to subclause 11.4.3.
// Upon reception of a RESET ACK PDU, the RLC entity takes no action.
// Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity is suspended and enters the LOCAL_SUSPEND state.
if ((rlc->rlc_am_timer_list.head)) {
umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds);
}
rlc_am_demux_routing (rlc, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA, data_indP);
break;
case RLC_RESET_PENDING_STATE:
case RLC_RESET_AND_SUSPEND_STATE:
case RLC_LOCAL_SUSPEND_STATE:
// from 3GPP TS 25.322 V4.2.0
// In the RESET_PENDING state the entity waits for a response from its peer entity and no data can be exchanged between the entities.
// Upon reception of a CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity:
// - acts according to subclause 11.4.4; and
// - enters the DATA_TRANSFER_READY state.
// Upon reception of a RESET ACK PDU with a different RSN value as in the corresponding RESET PDU, the RLC entity:
// - discards the RESET ACK PDU (see subclause 11.4.4); and
// - stays in the RESET_PENDING state.
// Upon reception of a RESET PDU, the RLC entity:
// - responds according to subclause 11.4.3; and
// - stays in the RESET_PENDING state.
// Upon reception of CRLC-SUSPEND-Req from upper layer, the RLC entity:
// - enters the RESET_AND_SUSPEND state.
// In the RESET_ AND_SUSPEND state, the entity waits for a response from its peer entity or a primitive (CRLC-RESUME-Req) from its upper layer and no data can be exchanged between the entities.
// Upon reception of CRLC-CONFIG-Req from upper layer indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon reception of a RESET ACK PDU with the same RSN value as in the corresponding RESET PDU, the RLC entity:
// - acts according to subclause 11.4.4; and
// - enters the LOCAL_SUSPEND state.
// Upon reception of CRLC-RESUME-Req from upper layer in this state, the RLC entity:
// - is resumed, i.e. releases the suspend constraint; and
// - enters the RESET_PENDING state.
// from 3GPP TS 25.322 V4.2.0
// In the LOCAL_SUSPEND state, the RLC entity is suspended, i.e. it does not send AMD PDUs with SN greater than or equal to certain specified value (see subclause 9.7.5).
// Upon reception of CRLC-RESUME-Req from upper layers in this state, the RLC entity:
// - resumes the data transmission; and
// - enters the DATA_TRANSFER_READY state.
// Upon reception of CRLC-CONFIG-Req from upper layers indicating release, the RLC entity:
// - enters the NULL state; and
// - is considered as being terminated.
// Upon detection of an initiating condition for RLC reset procedure described in subclause 11.4.2, the RLC entity:
// - initiates the RLC reset procedure (see subclause 11.4); and
// - enters the RESET_AND_SUSPEND state.
if ((rlc->rlc_am_timer_list.head)) {
umts_timer_check_time_out (&rlc->rlc_am_timer_list, *rlc->frame_tick_milliseconds);
}
rlc_am_demux_routing (rlc, RLC_AM_TRAFFIC_NOT_ALLOWED, data_indP);
break;
default:
msg ("[RLC_AM %p] TX UNKNOWN PROTOCOL STATE 0x%02X\n", rlc, rlc->protocol_state);
}
}
//-----------------------------------------------------------------------------
struct mac_status_resp
rlc_am_mac_status_indication (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP)
{
//-----------------------------------------------------------------------------
struct mac_status_resp status_resp;
struct rlc_am_entity *rlc = (struct rlc_am_entity *) rlcP;
rlc_am_discard_check_sdu_time_out (rlc);
// call only for knowing if control pdu to transmit
// special case: no data at startup on this side, but peer entity tx full sspeed
// peer entity wqit for acks
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS);
rlc->nb_pdu_requested_by_mac_on_ch1 = no_tbP;
//((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM
status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 (rlc);
status_resp.buffer_occupancy_in_pdus += rlc_am_get_buffer_occupancy_in_pdus_ch2 (rlc);
status_resp.buffer_occupancy_in_pdus += rlc->control.nb_elements;
status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * (rlc)->pdu_size;
status_resp.rlc_info.rlc_protocol_state = (rlc)->protocol_state;
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] MAC_STATUS_INDICATION %d TBs -> MAC_STATUS_RESPONSE %d TBs FRAME %d\n", rlc->rb_id, no_tbP, status_resp.buffer_occupancy_in_pdus,Mac_rlc_xface->frame);
#endif
return status_resp;
}
//-----------------------------------------------------------------------------
struct mac_status_resp
rlc_am_mac_status_indication_on_first_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP)
{
//-----------------------------------------------------------------------------
struct mac_status_resp status_resp;
rlc_am_discard_check_sdu_time_out ((struct rlc_am_entity *) rlcP);
((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 = no_tbP;
//((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM
status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP);
status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size;
status_resp.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state;
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] CHANNEL 1 MAC_STATUS_INDICATION (DATA) %d TBs -> MAC_STATUS_RESPONSE %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, no_tbP, status_resp.buffer_occupancy_in_pdus);
#endif
return status_resp;
}
//-----------------------------------------------------------------------------
struct mac_status_resp
rlc_am_mac_status_indication_on_second_channel (void *rlcP, uint16_t no_tbP, uint16_t tb_sizeP, struct mac_status_ind tx_statusP)
{
//-----------------------------------------------------------------------------
struct mac_status_resp status_resp;
rlc_am_discard_check_sdu_time_out ((struct rlc_am_entity *) rlcP);
((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch2 = no_tbP;
//((struct rlc_am_entity*)rlcP)->rlc_pdu_size = tb_sizeP; no modification of pdu_size for RLC AM
status_resp.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP);
status_resp.buffer_occupancy_in_bytes = status_resp.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size;
status_resp.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state;
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] CHANNEL 2 MAC_STATUS_INDICATION (CONTROL) %d TBs -> MAC_STATUS_RESPONSE %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, no_tbP, status_resp.buffer_occupancy_in_pdus);
#endif
return status_resp;
}
//-----------------------------------------------------------------------------
struct mac_data_req
rlc_am_mac_data_request (void *rlcP)
{
//-----------------------------------------------------------------------------
struct mac_data_req data_req;
mem_block_t *pdu;
signed int nb_pdu_to_transmit = ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 ;
//rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
list_init (&data_req.data, NULL);
//list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1, &data_req.data);
while (nb_pdu_to_transmit > 0 ) {
pdu = list_remove_head (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1);
if (pdu != null) {
list_add_tail_eurecom (pdu, &data_req.data);
} else {
//msg ("[RLC_AM][RB %d] WARNING MAC_DATA_REQUEST CANNOT GIVE A PDU REQUESTED BY MAC\n", ((struct rlc_am_entity *) rlcP)->rb_id);
}
nb_pdu_to_transmit = nb_pdu_to_transmit - 1;
}
//list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch2, &data_req.data);
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST %d TBs (REQUESTED %d) Frame %d\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements, ((struct rlc_am_entity *) rlcP)->nb_pdu_requested_by_mac_on_ch1 , Mac_rlc_xface->frame);
#endif
data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP);
data_req.buffer_occupancy_in_pdus += rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP);
data_req.buffer_occupancy_in_bytes = data_req.buffer_occupancy_in_pdus * ((struct rlc_am_entity *) rlcP)->pdu_size;
data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state;
return data_req;
}
//-----------------------------------------------------------------------------
struct mac_data_req
rlc_am_mac_data_request_on_first_channel (void *rlcP)
{
//-----------------------------------------------------------------------------
struct mac_data_req data_req;
// from TS25.322 V4.2.0 p13
// In case two logical channels are configured in the uplink, AMD PDUs are transmitted
// on the first logical channel, and control PDUs are transmitted on the second logical
// channel. In case two logical channels are configured in the downlink, AMD and Control
// PDUs can be transmitted on any of the two logical channels.
#ifdef NODE_RG
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
#else
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
#endif
list_init (&data_req.data, NULL);
list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch1, &data_req.data);
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST (DATA) %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements);
#endif
data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch1 ((struct rlc_am_entity *) rlcP);
data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes_ch1 ((struct rlc_am_entity *) rlcP);
data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state;
return data_req;
}
//-----------------------------------------------------------------------------
struct mac_data_req
rlc_am_mac_data_request_on_second_channel (void *rlcP)
{
//-----------------------------------------------------------------------------
struct mac_data_req data_req;
// from TS25.322 V4.2.0 p13
// In case two logical channels are configured in the uplink, AMD PDUs are transmitted
// on the first logical channel, and control PDUs are transmitted on the second logical
// channel. In case two logical channels are configured in the downlink, AMD and Control
// PDUs can be transmitted on any of the two logical channels.
#ifdef NODE_RG
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS | RLC_AM_TRAFFIC_ALLOWED_FOR_DATA);
#else
rlc_am_get_pdus (rlcP, RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS);
#endif
list_init (&data_req.data, NULL);
list_add_list (&((struct rlc_am_entity *) rlcP)->pdus_to_mac_layer_ch2, &data_req.data);
#ifdef DEBUG_RLC_AM_TX
msg ("[RLC_AM][RB %d] MAC_DATA_REQUEST (CONTROL) %d TBs\n", ((struct rlc_am_entity *) rlcP)->rb_id, data_req.data.nb_elements);
#endif
data_req.buffer_occupancy_in_pdus = rlc_am_get_buffer_occupancy_in_pdus_ch2 ((struct rlc_am_entity *) rlcP);
data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes_ch2 ((struct rlc_am_entity *) rlcP);
data_req.rlc_info.rlc_protocol_state = ((struct rlc_am_entity *) rlcP)->protocol_state;
return data_req;
}
//-----------------------------------------------------------------------------
void
rlc_am_mac_data_indication (void *rlcP, struct mac_data_ind data_indP)
{
//-----------------------------------------------------------------------------
rlc_am_rx (rlcP, data_indP);
}
//-----------------------------------------------------------------------------
void
rlc_am_data_req (void *rlcP, mem_block_t * sduP)
{
//-----------------------------------------------------------------------------
struct rlc_am_entity *rlc = (struct rlc_am_entity *) rlcP;
uint32_t mui;
uint16_t data_offset;
uint16_t data_size;
uint8_t conf;
if ((rlc->input_sdus[rlc->next_sdu_index] == NULL) && (((rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer) != rlc->current_sdu_index)) {
rlc->stat_tx_pdcp_sdu += 1;
rlc->input_sdus[rlc->next_sdu_index] = sduP;
mui = ((struct rlc_am_data_req *) (sduP->data))->mui;
data_offset = ((struct rlc_am_data_req *) (sduP->data))->data_offset;
data_size = ((struct rlc_am_data_req *) (sduP->data))->data_size;
conf = ((struct rlc_am_data_req *) (sduP->data))->conf;
((struct rlc_am_tx_sdu_management *) (sduP->data))->mui = mui;
((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size = data_size;
((struct rlc_am_tx_sdu_management *) (sduP->data))->confirm = conf;
rlc->buffer_occupancy += ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size;
rlc->nb_sdu += 1;
((struct rlc_am_tx_sdu_management *) (sduP->data))->first_byte = &sduP->data[data_offset];
((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_remaining_size = ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size;
((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_segmented_size = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_creation_time = *rlc->frame_tick_milliseconds;
((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_ack = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_time = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_internal_use = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->segmented = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->discarded = 0;
((struct rlc_am_tx_sdu_management *) (sduP->data))->li_index_for_discard = -1;
((struct rlc_am_tx_sdu_management *) (sduP->data))->no_new_sdu_segmented_in_last_pdu = 0;
rlc->next_sdu_index = (rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer;
#ifdef DEBUG_RLC_AM_DATA_REQUEST
msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d ",
rlc->rb_id, data_size, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, conf, mui);
msg ("BO=%ld Bytes\n", rlc->buffer_occupancy);
#endif
} else {
#ifdef DEBUG_RLC_AM_DATA_REQUEST
msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d\n",
rlc->rb_id, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, rlc->size_input_sdus_buffer);
#endif
rlc->stat_tx_pdcp_sdu_discarded += 1;
free_mem_block (sduP);
}
}
-153
View File
@@ -1,153 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_constant.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_CONSTANT_H__
# define __RLC_AM_CONSTANT_H__
# define RLC_AM_LOCATION_UTRAN 0xBA
# define RLC_AM_LOCATION_UE 0x01
//----------------------------------------------------------
// AMD DATA, CONTROL PDU parameters
//----------------------------------------------------------
# define NB_MAX_SUFI 30
# define SUFI_MAX_SIZE 40
// SUFI field (4 bits)
# define RLC_AM_SUFI_NO_MORE 0x0
# define RLC_AM_SUFI_WINDOW 0x1
# define RLC_AM_SUFI_ACK 0x2
# define RLC_AM_SUFI_LIST 0x3
# define RLC_AM_SUFI_BITMAP 0x4
# define RLC_AM_SUFI_RLIST 0x5
# define RLC_AM_SUFI_MRW 0x6
# define RLC_AM_SUFI_MRW_ACK 0x7
# define RLC_AM_SUFI_NO_MORE_SIZE 4
//in bits
# define RLC_AM_SUFI_ACK_SIZE 16
//in bits
# define RLC_AM_SUFI_LIST_SIZE_MIN 24
//in bits
# define RLC_AM_SUFI_BITMAP_SIZE_MIN 28
//in bits
//----------------------------------------------------------
// values for ack field of struct rlc_am_tx_pdu_management
// this struct is mapped on the misc field of each pdu
# define RLC_AM_PDU_ACK_NO_EVENT 0
# define RLC_AM_PDU_ACK_EVENT 1
# define RLC_AM_PDU_NACK_EVENT -1
//----------------------------------------------------------
# define RLC_AM_SEND_MRW_OFF 0x0F
# define RLC_AM_SEND_MRW_ON 0xF0
//----------------------------------------------------------
// SN Field
# define RLC_AM_SN_1ST_PART_MASK 0x7F
# define RLC_AM_SN_2ND_PART_MASK 0xF8
//----------------------------------------------------------
// Polling bit (values shifted 2 bits left)
# define RLC_AM_P_STATUS_REPORT_NOT_REQUESTED 0
# define RLC_AM_P_STATUS_REPORT_REQUESTED 4
# define RLC_AM_P_STATUS_REPORT_MASK 4
//----------------------------------------------------------
// li field (values shifted 1 bit left)
# define RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU 32
//----------------------------------------------------------
// shifted 3 bits left
# define RLC_AM_RESET_SEQUENCE_NUMBER_MASK 0x08
# define RLC_AM_TIMER_POLL_TIME_OUT_EVENT 0x001
# define RLC_AM_TIMER_POLL_PROHIBIT_TIME_OUT_EVENT 0x002
# define RLC_AM_TIMER_EPC_TIME_OUT_EVENT 0x004
# define RLC_AM_TIMER_DISCARD_TIME_OUT_EVENT 0x008
# define RLC_AM_TIMER_POLL_PERIODIC_TIME_OUT_EVENT 0x010
# define RLC_AM_TIMER_STATUS_PROHIBIT_TIME_OUT_EVENT 0x020
# define RLC_AM_TIMER_STATUS_PERIODIC_TIME_OUT_EVENT 0x040
# define RLC_AM_TIMER_RST_TIME_OUT_EVENT 0x080
# define RLC_AM_TIMER_MRW_TIME_OUT_EVENT 0x100
//----------------------------------------------------------
# define RLC_AM_SDU_SEGMENTS_SUBMITTED_TO_LOWER_LAYER 0xFF
// for sdu_header_copy
# define RLC_AM_SN_INVALID 0xFFFF
// PDU transmission
# define RLC_AM_PDU_COPY_LOCATION_RETRANSMISSION_BUFFER_TO_SEND 0x10
# define RLC_AM_PDU_COPY_LOCATION_PDUS_TO_MAC_LAYER 0x20
# define RLC_AM_PDU_COPY_LOCATION_MASK 0xF0
//----------------------------------------------------------
// Events defined for state model of the acknowledged mode entity
# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT 0x00
# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT 0x01
# define RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT 0x10
# define RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT 0x11
# define RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT 0x12
# define RLC_AM_RECEIVE_RESET_EVENT 0x20
# define RLC_AM_TRANSMIT_RESET_EVENT 0x21
# define RLC_AM_RECEIVE_RESET_ACK_EVENT 0x22
# define RLC_AM_TRANSMIT_RESET_ACK_EVENT 0x23
//----------------------------------------------------------
# define RLC_AM_TRAFFIC_NOT_ALLOWED 0x00
# define RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS 0xC0
// mutual exclusion of set bits with next value
# define RLC_AM_TRAFFIC_ALLOWED_FOR_DATA 0x0D
// mutual exclusion of set bits with previous value
# define RLC_AM_DCCH_ID 0xC0
// mutual exclusion of set bits with next value
# define RLC_AM_DTCH_ID 0x0D
// mutual exclusion of set bits with previous value
//----------------------------------------------------------
// for status report of transmission by MAC layer
# define RLC_AM_STATUS_PDU_TYPE 0x0001
# define RLC_AM_FIRST_STATUS_PDU_TYPE 0x0011
# define RLC_AM_LAST_STATUS_PDU_TYPE 0x0021
# define RLC_AM_MRW_STATUS_PDU_TYPE 0x0040
# define RLC_AM_RESET_PDU_TYPE 0x0080
# define RLC_AM_RESET_ACK_PDU_TYPE 0x0100
# define RLC_AM_DATA_POLL_PDU_TYPE 0x1800
# define RLC_AM_DATA_PDU_TYPE 0x1000
//----------------------------------------------------------
// TIMER EPC
# define TIMER_EPC_STATE_IDLE 0x00
# define TIMER_EPC_STATE_TIMER_ARMED 0x01
# define TIMER_EPC_STATE_TIMED_OUT 0x02
# define TIMER_EPC_STATE_VR_EP_COUNTING_DOWN 0x04
# define TIMER_EPC_STATE_VR_EP_EQUAL_ZERO 0x08
# define TIMER_EPC_PDU_STATUS_SUBMITTED_LOWER_LAYER_EVENT 0x01
# define TIMER_EPC_PDU_STATUS_TRANSMITED_EVENT 0x02
# define TIMER_EPC_TIMER_TIMED_OUT_EVENT 0x04
# define TIMER_EPC_VR_EP_EQUAL_ZERO_EVENT 0x08
# endif
@@ -1,466 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_control_primitives.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc_am_entity.h"
#include "rlc_am_reset_proto_extern.h"
#include "rlc_am_errno.h"
#include "umts_timer_proto_extern.h"
#include "rlc_primitives.h"
#include "rlc_am_fsm_proto_extern.h"
#include "rlc_am_segment_proto_extern.h"
#include "rrm_config_structs.h"
#include "LAYER2/MAC/extern.h"
//-----------------------------------------------------------------------------
void config_req_rlc_am (struct rlc_am_entity *rlcP, module_id_t module_idP, rlc_am_info_t * config_amP, uint8_t rb_idP, rb_type_t rb_typeP);
void send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP);
void init_rlc_am (struct rlc_am_entity *rlcP);
void rlc_am_reset_state_variables (struct rlc_am_entity *rlcP);
void rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity *rlcP);
void rlc_am_discard_all_pdus (struct rlc_am_entity *rlcP);
void rlc_am_stop_all_timers (struct rlc_am_entity *rlcP);
void rlc_am_free_all_resources (struct rlc_am_entity *rlcP);
void rlc_am_set_configured_parameters (struct rlc_am_entity *rlcP, mem_block_t * cprimitiveP);
//void rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP);
//-----------------------------------------------------------------------------
/*void
rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP)
{
//-----------------------------------------------------------------------------
if (rlcP->protocol_state != RLC_NULL_STATE) {
reportP->incoming_sdu[measurement_indexP] = rlcP->buffer_occupancy;
reportP->retransmission[measurement_indexP] = rlcP->buffer_occupancy_retransmission_buffer * rlcP->pdu_size;
reportP->ready_to_send[measurement_indexP] = (rlcP->pdus_to_mac_layer_ch1.nb_elements + rlcP->pdus_to_mac_layer_ch2.nb_elements) * rlcP->pdu_size;
}
}*/
//-----------------------------------------------------------------------------
void
config_req_rlc_am (struct rlc_am_entity *rlcP, module_id_t module_idP, rlc_am_info_t * config_amP, uint8_t rb_idP, rb_type_t rb_typeP)
{
//-----------------------------------------------------------------------------
mem_block_t *mb;
mb = get_free_mem_block (sizeof (struct crlc_primitive));
((struct crlc_primitive *) mb->data)->type = CRLC_CONFIG_REQ;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.e_r = RLC_E_R_ESTABLISHMENT;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.stop = 0;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.cont = 1;
// timers
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll = config_amP->timer_poll;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_prohibit = config_amP->timer_poll_prohibit;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_discard = config_amP->timer_discard;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_periodic = config_amP->timer_poll_periodic;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_status_prohibit = config_amP->timer_status_prohibit;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_status_periodic = config_amP->timer_status_periodic;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_rst = config_amP->timer_rst;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.max_rst = config_amP->max_rst;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.timer_mrw = config_amP->timer_mrw;
// protocol_parameters
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.pdu_size = config_amP->pdu_size;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.max_dat = config_amP->max_dat;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_pdu = config_amP->poll_pdu;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_sdu = config_amP->poll_sdu;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.poll_window = config_amP->poll_window;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.configured_tx_window_size = config_amP->tx_window_size;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.configured_rx_window_size = config_amP->rx_window_size;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.max_mrw = config_amP->max_mrw;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.last_transmission_pdu_poll_trigger = config_amP->last_transmission_pdu_poll_trigger;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.last_retransmission_pdu_poll_trigger = config_amP->last_retransmission_pdu_poll_trigger;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.sdu_discard_mode = config_amP->sdu_discard_mode;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.send_mrw = config_amP->send_mrw;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.frame_tick_milliseconds = &mac_xface->frame;
((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.am_parameters.rb_id = rb_idP;
send_rlc_am_control_primitive (rlcP, module_idP, mb);
if (rb_typeP != SIGNALLING_RADIO_BEARER) {
rlcP->data_plane = 1;
msg ("[RLC AM][RB %d] DATA PLANE\n", rlcP->rb_id);
} else {
rlcP->data_plane = 0;
msg ("[RLC AM][RB %d] CONTROL PLANE\n", rlcP->rb_id);
}
}
//-----------------------------------------------------------------------------
void
send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP)
{
//-----------------------------------------------------------------------------
rlcP->module_id = module_idP;
switch (((struct crlc_primitive *) cprimitiveP->data)->type) {
case CRLC_CONFIG_REQ:
switch (((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.e_r) {
case RLC_E_R_ESTABLISHMENT:
if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) {
rlc_am_set_configured_parameters (rlcP, cprimitiveP); // the order of the calling of procedures...
rlc_am_reset_state_variables (rlcP); // ...must not ...
rlc_am_alloc_buffers_after_establishment (rlcP); // ...be changed
}
break;
case RLC_E_R_RE_ESTABLISHMENT:
// from 3GPP TS 25.322 V4.2.0(2001-09)
// The RLC re-establishment function is applicable for AM and UM and is used when upper layers request an RLC entity to be re-established.
// When an RLC entity is re-established by upper layers, the RLC entity shall:
// - reset the state variables to their initial value;
// - set the configurable parameters to their configured value;
// - set the hyper frame number (HFN) in UL and DL to the value configured by upper layers;
// - if the RLC entity is operating in unacknowledged mode:
// - if it is a receiving UM RLC entity:
// - discard all UMD PDUs;
// - if it is a transmitting UM RLC entity:
// - discard the RLC SDUs for which one or more segments have been submitted to a lower layer;
// - otherwise if the RLC entity is operating in acknowledged mode:
// - discard all AMD PDUs in the Receiver and Sender.
if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) {
rlc_am_free_all_resources (rlcP);
rlc_am_set_configured_parameters (rlcP, cprimitiveP); // the order of the calling of procedures...
rlc_am_reset_state_variables (rlcP); // ...must not ...
rlc_am_alloc_buffers_after_establishment (rlcP); // ...be changed
}
break;
case RLC_E_R_MODIFICATION:
msg ("[RLC_AM][RB %d] WARNING CRLC_CONFIG_REQ:RLC_AM_E_R_MODIFICATION NOT IMPLEMENTED AT ALL: MAY BE BUGGY IF CHANGING WINDOWS SIZE\n", rlcP->rb_id);
rlc_am_set_configured_parameters (rlcP, cprimitiveP);
break;
case RLC_E_R_RELEASE:
if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT)) {
rlc_am_free_all_resources (rlcP);
}
break;
default:
msg ("[RLC_AM][ERROR] control_rlc_am(CRLC_CONFIG_REQ) unknown parameter E_R\n");
}
break;
case CRLC_SUSPEND_REQ:
// from 3GPP TS 25.322 V4.2.0(2001-09)
// When an RLC entity operating in acknowledged mode is suspended by upper layers with the parameter N, the RLC entity shall:
// - acknowledge the suspend request with a confirmation containing the current value of VT(S);
// - not send AMD PDUs with sequence number SNVT(S)+N.
if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT)) {
if ((rlcP->protocol_state == RLC_LOCAL_SUSPEND_STATE) || (rlcP->protocol_state == RLC_LOCAL_SUSPEND_STATE)) {
// TO DO IN FUTURE, BUT IT SEEMS THERE IS NO NEED TO IMPLEMENT THIS FUNCTION IN THE CURRENTLY DEFINED ARCHITECTURE
// SO DISPLAY ERROR MESSAGE
msg ("[RLC_AM[RB %d] ERROR RECEIVED CRLC_SUSPEND_REQ NOT IMPLEMENTED AT ALL, RLC_AM MAY NOT WORK AS EXPECTED IN THE 3GPP SPECIFICATION\n", rlcP->rb_id);
}
}
break;
case CRLC_RESUME_REQ:
// from 3GPP TS 25.322 V4.2.0(2001-09)
// When an RLC entity operating in acknowledged mode is resumed by upper layers, the RLC entity shall:
// - if the RLC entity is suspended and a RLC Reset procedure is not ongoing:
// - resume data transfer procedure.
// - otherwise, if the RLC entity is suspended and a RLC Reset procedure is ongoing:
// - remove the suspend constraint;
// - resume the RLC reset procedure according to subclause 11.4.
if (rlc_am_fsm_notify_event (rlcP, RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT)) {
if ((rlcP->protocol_state == RLC_RESET_PENDING_STATE) || (rlcP->protocol_state == RLC_DATA_TRANSFER_READY_STATE)) {
// TO DO IN FUTURE, BUT IT SEEMS THERE IS NO NEED TO IMPLEMENT THIS FUNCTION IN THE CURRENTLY DEFINED ARCHITECTURE
// SO DISPLAY ERROR MESSAGE
msg ("[RLC_AM][RB %d] ERROR RECEIVED CRLC_RESUME_REQ NOT IMPLEMENTED AT ALL, RLC_AM MAY NOT WORK AS EXPECTED IN THE 3GPP SPECIFICATION\n", rlcP->rb_id);
}
}
break;
default:
msg ("[RLC_AM][RB %d][ERROR] control_rlc_am(UNKNOWN CPRIMITIVE)\n", rlcP->rb_id);
}
free_mem_block (cprimitiveP);
}
//-----------------------------------------------------------------------------
void
init_rlc_am (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
memset (rlcP, 0, sizeof (struct rlc_am_entity));
list2_init (&rlcP->retransmission_buffer_to_send, NULL);
list_init (&rlcP->pdus_to_mac_layer_ch1, NULL);
list_init (&rlcP->pdus_to_mac_layer_ch2, NULL);
list_init (&rlcP->pdus_from_mac_layer_ch1, NULL);
list_init (&rlcP->pdus_from_mac_layer_ch2, NULL);
list_init (&rlcP->control, NULL);
list2_init (&rlcP->sdu_conf_segmented, NULL);
list2_init (&rlcP->sdu_discard_segmented, NULL);
list2_init (&rlcP->sdu_discarded, NULL);
list2_init (&rlcP->rlc_am_timer_list, NULL);
rlcP->protocol_state = RLC_NULL_STATE;
rlcP->next_sdu_index = 0;
rlcP->current_sdu_index = 0;
rlcP->last_received_rsn = 0xFF;
//--------------------------------------------------------------------------
rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0;
rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; // =>not activated
rlcP->stat_tx_pdcp_sdu = 0;
rlcP->stat_tx_pdcp_sdu_discarded = 0;
rlcP->stat_tx_retransmit_pdu_unblock = 0;
rlcP->stat_tx_retransmit_pdu_by_status = 0;
rlcP->stat_tx_data_pdu = 0;
rlcP->stat_tx_control_pdu = 0;
rlcP->stat_rx_sdu = 0;
rlcP->stat_rx_error_pdu = 0;
rlcP->stat_rx_data_pdu = 0;
rlcP->stat_rx_data_pdu_out_of_window = 0;
rlcP->stat_rx_control_pdu = 0;
}
//-----------------------------------------------------------------------------
void
rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
rlcP->recomputed_configured_tx_window_size = 1;
while (rlcP->recomputed_configured_tx_window_size < rlcP->configured_tx_window_size) {
rlcP->recomputed_configured_tx_window_size = rlcP->recomputed_configured_tx_window_size << 1;
}
rlcP->retransmission_buffer_alloc = get_free_mem_block (rlcP->recomputed_configured_tx_window_size * sizeof (mem_block_t *));
rlcP->retransmission_buffer = (mem_block_t **) (rlcP->retransmission_buffer_alloc->data);
//memset (rlcP->retransmission_buffer, 0, rlcP->recomputed_configured_tx_window_size * sizeof (mem_block_t *));
rlcP->recomputed_configured_rx_window_size = 1;
while (rlcP->recomputed_configured_rx_window_size < rlcP->configured_rx_window_size) {
rlcP->recomputed_configured_rx_window_size = rlcP->recomputed_configured_rx_window_size << 1;
}
rlcP->receiver_buffer_alloc = get_free_mem_block (rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t *));
rlcP->receiver_buffer = (mem_block_t **) (rlcP->receiver_buffer_alloc->data);
msg("[RLC AM][RB %d] Window size %d\n",rlcP->rb_id,rlcP->recomputed_configured_rx_window_size);
//memset (rlcP->receiver_buffer, 0, rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t *));
rlcP->holes_alloc = get_free_mem_block ((rlcP->recomputed_configured_rx_window_size * sizeof (struct rlc_am_hole)) >> 1);
rlcP->holes = (struct rlc_am_hole *) (rlcP->holes_alloc->data);
//memset (rlcP->holes_alloc->data, 0, (rlcP->recomputed_configured_rx_window_size * sizeof (mem_block_t *)) >> 1);
rlcP->size_input_sdus_buffer = rlcP->recomputed_configured_tx_window_size * 4;
if ((rlcP->input_sdus_alloc == NULL)) {
rlcP->input_sdus_alloc = get_free_mem_block (rlcP->size_input_sdus_buffer * sizeof (void *));
rlcP->input_sdus = (mem_block_t **) (rlcP->input_sdus_alloc->data);
//memset (rlcP->input_sdus, 0, rlcP->size_input_sdus_buffer * sizeof (void *));
}
}
//-----------------------------------------------------------------------------
void
rlc_am_reset_state_variables (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
rlcP->vt_s = 0;
rlcP->vt_a = 0;
rlcP->vt_pdu = 0;
//................................................................
rlcP->vt_sdu = 0;
rlcP->vt_mrw = 0;
rlcP->vt_ms = rlcP->configured_tx_window_size - 1;
//................................................................
rlcP->vt_ws = rlcP->configured_tx_window_size;
rlcP->vr_r = 0;
rlcP->vr_h = 0;
//................................................................
rlcP->vr_mr = rlcP->configured_rx_window_size - 1;
rlcP->vt_rst = 0;
//................................................................
rlcP->send_status_pdu_requested = 0;
rlcP->first_li_in_next_pdu = RLC_LI_UNDEFINED;
rlcP->last_reassemblied_sn = SN_12BITS_MASK;
rlcP->li_exactly_filled_to_add_in_next_pdu = 0;
rlcP->li_one_byte_short_to_add_in_next_pdu = 0;
//................................................................
rlcP->sufi_to_insert_index = 0;
rlcP->ack.vr_r_modified = 0;
rlcP->ack.ack_other_vr_r = 0;
//................................................................
rlcP->output_sdu_size_to_write = 0;
rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0;
rlcP->discard_reassembly_start_sn = RLC_AM_SN_INVALID; // =>not activated
//................................................................
rlcP->timer_mrw = NULL;
//................................................................
rlcP->buffer_occupancy = 0;
rlcP->nb_sdu = 0;
rlcP->buffer_occupancy_retransmission_buffer = 0;
rlcP->next_sdu_index = 0;
rlcP->current_sdu_index = 0;
rlcP->nb_pdu_requested_by_mac_on_ch1 = 0;
rlcP->nb_pdu_requested_by_mac_on_ch2 = 0;
rlcP->running_timer_status_prohibit = rlcP->timer_status_prohibit/10;
}
//-----------------------------------------------------------------------------
void
rlc_am_stop_all_timers (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
list2_free (&rlcP->rlc_am_timer_list);
}
//-----------------------------------------------------------------------------
void
rlc_am_discard_all_pdus (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
uint16_t index;
index = 0;
while (index < rlcP->recomputed_configured_rx_window_size) {
if (rlcP->receiver_buffer[index] != NULL) {
free_mem_block (rlcP->receiver_buffer[index]);
rlcP->receiver_buffer[index] = NULL;
}
index++;
}
index = 0;
while (index < rlcP->recomputed_configured_tx_window_size) {
if (rlcP->retransmission_buffer[index] != NULL) {
free_mem_block (rlcP->retransmission_buffer[index]);
rlcP->retransmission_buffer[index] = NULL;
}
index++;
}
list2_free (&rlcP->retransmission_buffer_to_send);
list_free (&rlcP->pdus_to_mac_layer_ch1);
list_free (&rlcP->pdus_to_mac_layer_ch2);
list_free (&rlcP->control);
if ((rlcP->output_sdu_in_construction)) {
free_mem_block (rlcP->output_sdu_in_construction);
rlcP->output_sdu_in_construction = NULL;
}
}
//-----------------------------------------------------------------------------
void
rlc_am_free_all_resources (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
int index;
for (index = 0; index < rlcP->size_input_sdus_buffer; index++) {
if (rlcP->input_sdus[index]) {
free_mem_block (rlcP->input_sdus[index]);
rlcP->input_sdus[index] = NULL;
}
}
rlc_am_discard_all_pdus (rlcP);
if (rlcP->retransmission_buffer_alloc) {
free_mem_block (rlcP->retransmission_buffer_alloc);
}
if (rlcP->receiver_buffer_alloc) {
free_mem_block (rlcP->receiver_buffer_alloc);
}
if (rlcP->input_sdus_alloc) {
free_mem_block (rlcP->input_sdus_alloc);
}
if (rlcP->holes_alloc) {
free_mem_block (rlcP->holes_alloc);
}
rlcP->holes_alloc = NULL;
rlcP->input_sdus_alloc = NULL;
rlcP->receiver_buffer_alloc = NULL;
rlcP->retransmission_buffer_alloc = NULL;
rlc_am_stop_all_timers (rlcP);
}
//-----------------------------------------------------------------------------
void
rlc_am_set_configured_parameters (struct rlc_am_entity *rlcP, mem_block_t * cprimitiveP)
{
//-----------------------------------------------------------------------------
// timers
//rlcP->timer_poll_trigger = ((struct crlc_primitive *)cprimitiveP->data)->cprimitive.c_config_req.parameters.am_parameters.timer_poll;
//rlcP-> = ((struct crlc_primitive *)cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_prohibit;
rlcP->timer_discard_init = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_discard;
rlcP->timer_poll_periodic_init = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_poll_periodic;
rlcP-> timer_status_prohibit = ((struct crlc_primitive *)cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_status_prohibit;
rlcP->timer_status_periodic = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_status_periodic;
rlcP->timer_rst_init = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_rst;
rlcP->max_rst = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_rst;
rlcP->timer_mrw_init = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.timer_mrw;
// protocol_parameters
rlcP->pdu_size = (((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.pdu_size + 7) >> 3;
rlcP->max_dat = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_dat;
rlcP->missing_pdu_indicator = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.missing_pdu_indicator;
rlcP->poll_pdu_trigger = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_pdu;
rlcP->poll_sdu_trigger = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_sdu;
rlcP->last_transmission_pdu_poll_trigger = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.last_transmission_pdu_poll_trigger;
rlcP->last_retransmission_pdu_poll_trigger = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.last_retransmission_pdu_poll_trigger;
rlcP->poll_window_trigger = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.poll_window;
rlcP->configured_tx_window_size = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.configured_tx_window_size;
rlcP->configured_rx_window_size = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.configured_rx_window_size;
rlcP->max_mrw = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.max_mrw;
rlcP->sdu_discard_mode = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.sdu_discard_mode;
rlcP->send_mrw = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.send_mrw;
// SPARE : not 3GPP
rlcP->rb_id = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.rb_id;
rlcP->frame_tick_milliseconds = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.am_parameters.frame_tick_milliseconds;
rlcP->nb_logical_channels_per_rlc =1;
if (rlcP->pdu_size > 126) {
rlcP->rlc_segment = rlc_am_segment_15;
} else {
rlcP->rlc_segment = rlc_am_segment_7;
}
if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_RESET) {
msg ("[RLC AM][RB %d] SDU DISCARD RESET CONFIGURED\n", rlcP->rb_id);
} else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_TIMER_BASED_EXPLICIT) {
msg ("[RLC AM][RB %d] SDU DISCARD TIMER BASED EXPLICIT SIGNALING CONFIGURED\n", rlcP->rb_id);
} else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_MAX_DAT_RETRANSMISSION) {
msg ("[RLC AM][RB %d] SDU DISCARD MAX RETRANSMISSION CONFIGURED\n", rlcP->rb_id);
} else if (rlcP->sdu_discard_mode == SDU_DISCARD_MODE_NOT_CONFIGURED) {
msg ("[RLC AM][RB %d] SDU DISCARD NOT CONFIGURED\n", rlcP->rb_id);
}
}
@@ -1,56 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_control_primitives_proto_extern.h -
-------------------
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_CONTROL_PRIMITIVES_H__
# define __RLC_AM_CONTROL_PRIMITIVES_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mem_block.h"
# include "rrm_config_structs.h"
//-----------------------------------------------------------------------------
extern void config_req_rlc_am (struct rlc_am_entity *rlcP, module_id_t module_idP, rlc_am_info_t * config_amP, uint8_t rb_idP, rb_type_t rb_typeP);
extern void send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP);
extern void init_rlc_am (struct rlc_am_entity *rlcP);
extern void rlc_am_reset_state_variables (struct rlc_am_entity *rlcP);
extern void rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity *rlcP);
extern void rlc_am_discard_all_pdus (struct rlc_am_entity *rlcP);
extern void rlc_am_stop_all_timers (struct rlc_am_entity *rlcP);
extern void rlc_am_free_all_resources (struct rlc_am_entity *rlcP);
extern void rlc_am_set_configured_parameters (struct rlc_am_entity *rlcP, mem_block_t * cprimitiveP);
//extern void rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP);
# endif
-214
View File
@@ -1,214 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_demux.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
//#include "mac_log_interface_struct.h"
#include "LAYER2/RLC/rlc.h"
#include "mac_primitives.h"
#include "list.h"
#include "rlc_am_entity.h"
#include "rlc_am_structs.h"
#include "rlc_am_constants.h"
#include "rlc_am_receiver_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "rlc_am_status_proto_extern.h"
#include "rlc_am_timers_proto_extern.h"
#include "LAYER2/MAC/extern.h"
#define DEBUG_DEMUX_RESET
#define DEBUG_DEMUX
//-----------------------------------------------------------------------------
void
rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP)
{
//-----------------------------------------------------------------------------
struct rlc_am_pdu_header *data;
struct rlc_am_reset_header *control;
mem_block_t *tb;
uint8_t *first_byte;
uint16_t tb_size_in_bytes;
uint8_t first_bit;
uint8_t bits_to_shift;
uint8_t bits_to_shift_last_loop;
uint8_t data_received;
int index;
//-------------------------------------------------------
// D A T A P D U
//-------------------------------------------------------
data_received = 0;
while ((tb = list_remove_head (&data_indP.data))) {
if (!(((struct mac_tb_ind *) (tb->data))->error_indication)) {
first_byte = ((struct mac_tb_ind *) (tb->data))->data_ptr;
tb_size_in_bytes = data_indP.tb_size >> 3;
first_bit = ((struct mac_tb_ind *) (tb->data))->first_bit;
if (first_bit > 0) {
// shift data of transport_block TO CHECK
bits_to_shift_last_loop = 0;
while ((tb_size_in_bytes)) {
bits_to_shift = first_byte[tb_size_in_bytes] >> (8 - first_bit);
first_byte[tb_size_in_bytes] = (first_byte[tb_size_in_bytes] << first_bit) | (bits_to_shift_last_loop);
tb_size_in_bytes -= 1;
bits_to_shift_last_loop = bits_to_shift;
}
first_byte[0] = (first_byte[0] << first_bit) | (bits_to_shift_last_loop);
}
((struct rlc_am_rx_pdu_management *) (tb->data))->first_byte = first_byte;
data = (struct rlc_am_pdu_header *) (first_byte);
if ((data->byte1 & RLC_DC_MASK) == RLC_DC_DATA_PDU) {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX AMD PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
for (index=0; index < rlcP->pdu_size ; index++) {
msg("%02X.",first_byte[index]);
}
msg("\n");
#endif
rlcP->stat_rx_data_pdu += 1;
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
((struct rlc_am_rx_pdu_management *) (tb->data))->piggybacked_processed = 0;
receiver_retransmission_management (rlcP, tb, data);
// pdu is data;
data_received = 1;
} else {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] DROP DATA TB NOT ALLOWED IN PROTOCOL STATE 0x%02X\n", rlcP->rb_id, rlcP->protocol_state);
#endif
free_mem_block (tb);
}
} else {
rlcP->stat_rx_control_pdu += 1;
control = (struct rlc_am_reset_header *) first_byte;
if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_STATUS) {
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX STATUS PDU ON DTCH Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlc_am_process_status_info (rlcP, &(control->byte1));
}
} else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET) {
#ifdef DEBUG_DEMUX_RESET
msg ("[RLC_AM][RB %d][DEMUX] RX RESET PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
process_reset (tb, control, rlcP);
} else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET_ACK) {
#ifdef DEBUG_DEMUX_RESET
msg ("[RLC_AM][RB %d][DEMUX] RX RESET ACK PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
process_reset_ack (tb, control, rlcP);
#ifndef USER_MODE
rlc_info_t Rlc_info_am_config1;
Rlc_info_am_config1.rlc_mode=RLC_AM;
Rlc_info_am_config1.rlc.rlc_am_info.sdu_discard_mode = SDU_DISCARD_MODE_RESET;//SDU_DISCARD_MODE_MAX_DAT_RETRANSMISSION;//
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_prohibit = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_discard = 500;
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_periodic = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_status_prohibit = 250;
Rlc_info_am_config1.rlc.rlc_am_info.timer_status_periodic = 500;
Rlc_info_am_config1.rlc.rlc_am_info.timer_rst = 250;//250
Rlc_info_am_config1.rlc.rlc_am_info.max_rst = 500;//500
Rlc_info_am_config1.rlc.rlc_am_info.timer_mrw = 0;
Rlc_info_am_config1.rlc.rlc_am_info.pdu_size = 32; //416; // in bits
//Rlc_info_am.rlc.rlc_am_info.in_sequence_delivery = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.max_dat = 32;//127;
Rlc_info_am_config1.rlc.rlc_am_info.poll_pdu = 0;
Rlc_info_am_config1.rlc.rlc_am_info.poll_sdu = 0;//256;/
Rlc_info_am_config1.rlc.rlc_am_info.poll_window = 80;//128
Rlc_info_am_config1.rlc.rlc_am_info.tx_window_size = 512;
Rlc_info_am_config1.rlc.rlc_am_info.rx_window_size = 512;
Rlc_info_am_config1.rlc.rlc_am_info.max_mrw = 8;
Rlc_info_am_config1.rlc.rlc_am_info.last_transmission_pdu_poll_trigger = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.last_retransmission_pdu_poll_trigger = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.send_mrw = 1;//boolean*
Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_REMOVE,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1);
Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_ADD,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1);
#endif
}
free_mem_block (tb);
}
} else {
#ifdef BENCH_QOS_L2
fprintf (bench_l2, "[PDU RX ERROR] FRAME %d RLC-AM %p\n", Mac_rlc_xface->frame, rlcP);
#endif
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX PDU WITH ERROR INDICATION\n", rlcP->rb_id);
#endif
rlcP->stat_rx_error_pdu += 1;
free_mem_block (tb);
}
}
if ((data_received)) { //avoid call
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
if (rlcP->pdu_size <= 126) {
#ifdef DEBUG_DEMUX
msg("[RLC_AM][RB %d] Calling process_receiver_buffer_7\n",rlcP->rb_id);
#endif
process_receiver_buffer_7 (rlcP);
} else {
#ifdef DEBUG_DEMUX
msg("[RLC_AM][RB %d] Calling process_receiver_buffer_15\n",rlcP->rb_id);
#endif
process_receiver_buffer_15 (rlcP);
}
}
}
}
@@ -1,45 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_demux_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DEMUX_PROTO_EXTERN_H__
# define __RLC_AM_DEMUX_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mac_primitives.h"
//-----------------------------------------------------------------------------
extern void rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP);
# endif
@@ -1,391 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_notif.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#define RLC_AM_C
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc.h"
#include "rlc_primitives.h"
#include "rlc_am_status_proto_extern.h"
#include "umts_timer_struct.h"
#include "umts_timer_proto_extern.h"
#include "rlc_am_discard_tx_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "LAYER2/MAC/extern.h"
//-----------------------------------------------------------------------------
void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity *rlcP, mem_block_t * discard_procedureP);
void rlc_am_discard_notify_sdu_time_out (struct rlc_am_entity *rlcP, mem_block_t * sduP);
void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity *rlcP, mem_block_t * mbP);
//-----------------------------------------------------------------------------
// handler for timer
//-----------------------------------------------------------------------------
void
rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity *rlcP, mem_block_t * discard_procedureP)
{
//-----------------------------------------------------------------------------
/* from 3GPP TS 25.322 V5.5.0
If Timer_MRW expires before the discard procedure is terminated, the Sender shall:
- if VT(MRW)<MaxMRW-1:
- set the MRW SUFI as previously transmitted (even if additional SDUs were discarded in the mean-time);
- include the MRW SUFI in a new status report (if other SUFIs are included, their contents shall be updated);
- transmit the status report by either including it in a STATUS PDU or piggybacked in an AMD PDU;
- increment VT(MRW) by one;
- restart Timer_MRW for this discard procedure.
If the number of retransmission of an MRW SUFI (i.e. VT(MRW)) equals MaxMRW, the Sender shall:
- terminate the SDU discard with explicit signalling procedure;
- stop the timer Timer_MRW;
- deliver an error indication to upper layers;
- initiate the RLC RESET procedure */
rlcP->timer_mrw = NULL;
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT VT(MRW) %d PROCEDURE %p\n", rlcP->rb_id, rlcP->vt_mrw, discard_procedureP);
#endif
if ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0) {
// check the number of retransmission of the status pdu
if (rlcP->vt_mrw < (rlcP->max_mrw - 1)) {
rlc_am_schedule_procedure (rlcP);
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM %p][DISCARD] NOTIF MRW_ACK TIME OUT REARM TIMER\n", rlcP);
#endif
rlcP->vt_mrw += 1;
} else {
// TO DO : "deliver an error indication to upper layers"
#ifdef DEBUG_RESET
msg ("\n[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT MAX_MRW REACHED -> RESET\n", rlcP->rb_id);
#endif
send_reset_pdu (rlcP);
}
}
}
// handler for timer
//-----------------------------------------------------------------------------
void
rlc_am_discard_check_sdu_time_out (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
mem_block_t *sdu;
mem_block_t *pdu;
int discard_go_on;
int last_removed_pdu_sn;
int sn;
// TIMER BASED DISCARD
if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_EXPLICIT) && ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0)) {
/* from 3GPP TS 25.322 V5.0.0 p68
- if "Timer based SDU discard with explicit signalling" is configured:
- discard all SDUs up to and including the SDU for which the timer Timer_Discard expired.
- discard all AMD PDUs including segments of the discarded SDUs, unless they also carry a segment of a SDU
whose timer has not expired;
- if more than 15 discarded SDUs are to be informed to the Receiver:
- if "Send MRW" is not configured:
- assemble an MRW SUFI with the discard information of the SDUs.
- otherwise ("Send MRW" is configured):
- assemble an MRW SUFI with the discard information of the first 15 SDUs; and
- include the discard information of the rest SDUs in another MRW SUFI which shall be sent by the next
SDU discard with explicit signalling procedure (after the current SDU discard with explicit signalling
procedure is terminated).
- otherwise (less than or equal to 15 discarded SDUs are to be informed to the Receiver):
- assemble an MRW SUFI with the discard information of the SDUs.
- schedule and submit to lower layer a STATUS PDU/piggybacked STATUS PDU containing the MRW SUFI;
- if SN_MRWLENGTH in the MRW SUFI >VT(S):
- update VT(S) to SN_MRWLENGTH.
- start a timer Timer_MRW
If a new SDU discard with explicit signalling procedure is triggered when the timer Timer_MRW is active, no new
MRW SUFIs shall be sent before the current SDU discard with explicit signalling procedure is terminated by one of the
termination criteria.
*/
discard_go_on = 1;
last_removed_pdu_sn = -1;
while ((sdu = rlcP->input_sdus[rlcP->current_sdu_index]) && discard_go_on) {
if ((*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_creation_time) >= rlcP->timer_discard_init) {
// buffer occupancy is not updated at each generation of pdu, it is only updated for a sdu when the
// segmentation of this one is finished.
rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_remaining_size;
rlcP->nb_sdu -= 1;
if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON) ||
// the condition says if the sdu has generated one or more pdus
(((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_remaining_size)) {
((struct rlc_am_tx_sdu_management *) (sdu->data))->last_pdu_sn = rlcP->vt_s;
((struct rlc_am_tx_sdu_management *) (sdu->data))->no_new_sdu_segmented_in_last_pdu = 1;
rlcP->vt_s = (rlcP->vt_s + 1) & SN_12BITS_MASK;
list2_add_tail (sdu, &rlcP->sdu_discarded);
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING YES, TIMED OUT %ld ms frame %d ", rlcP->rb_id,
(*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_creation_time), Mac_rlc_xface->frame);
msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu);
display_protocol_vars_rlc_am (rlcP);
#endif
if (((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_remaining_size) {
// some pdu have to be removed if a sdu discarded generated almost one pdu
if (last_removed_pdu_sn == -1) {
sn = rlcP->vt_a;
} else {
sn = last_removed_pdu_sn;
}
while (sn != rlcP->vt_s) {
pdu = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size];
if ((pdu)) {
// now check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((((struct rlc_am_tx_data_pdu_management *) (pdu->data))->copy)) {
list2_remove_element (((struct rlc_am_tx_data_pdu_management *) (pdu->data))->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (((struct rlc_am_tx_data_pdu_management *) (pdu->data))->copy);
}
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management *) (pdu->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
free_mem_block (rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]);
rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL;
}
sn = (sn + 1) & SN_12BITS_MASK;
}
last_removed_pdu_sn = sn;
}
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING NO, TIMED OUT %ld ms ", rlcP->rb_id, (*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management *) (sdu->data))->sdu_creation_time));
msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu);
#endif
free_mem_block (sdu);
}
if (!(rlcP->data_plane)) {
#ifdef DEBUG_RLC_AM_SEND_CONFIRM
msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui);
#endif
rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE, rlcP->data_plane);
}
rlcP->input_sdus[rlcP->current_sdu_index] = NULL;
rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer;
// reset variables for segmentation
rlcP->li_exactly_filled_to_add_in_next_pdu = 0;
rlcP->li_one_byte_short_to_add_in_next_pdu = 0;
} else {
discard_go_on = 0;
}
}
}
}
//-----------------------------------------------------------------------------
void
rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity *rlcP, mem_block_t * pduP)
{
//-----------------------------------------------------------------------------
struct rlc_am_tx_data_pdu_management *pdu_mngt;
struct rlc_am_tx_sdu_management *sdu_mngt;
mem_block_t *pdu;
mem_block_t *pdu2;
mem_block_t *sdu;
int sdu_index;
int sdu_index2;
int pdu_index;
int last_sdu_index;
int sn;
pdu_mngt = (struct rlc_am_tx_data_pdu_management *) pduP->data;
// should never occur
//if (pdu_mngt->nb_sdu == 0) return;
// discard previous SDUS
#ifdef DEBUG_RLC_AM_DISCARD_MAX_DAT
msg ("[RLC_AM][RB %d] DISCARD MAX DAT PDU FRAME %d SN 0x%03X CONTAINS SDU INDEX ", rlcP->rb_id, Mac_rlc_xface->frame, pdu_mngt->sn);
sdu_index = 0;
while (sdu_index < pdu_mngt->nb_sdu) {
msg ("%d ", pdu_mngt->sdu[sdu_index]);
sdu_index += 1;
}
msg ("\n");
#endif
// From 3GPP TS25.322 V5.0.0 (2002-03) page 68
// - if "SDU discard after MaxDAT number of retransmissions" is configured:
// - discard all SDUs that have segments in AMD PDUs with SN inside the interval
// VT(A) <= SN <= X, where X is the value of the SN of the AMD PDU with VT(DAT) >= MaxDAT;
// - if requested
// - inform the upper layers of the discarded SDUs.
//---------------------------------------------------------------
// here delete all SDUs before the last sdu that have segments in the pdu discarded
sdu_index = rlcP->next_sdu_index;
last_sdu_index = pdu_mngt->sdu[pdu_mngt->nb_sdu - 1];
while (sdu_index != last_sdu_index) {
if ((sdu = rlcP->input_sdus[sdu_index])) {
list2_add_tail (sdu, &rlcP->sdu_discarded);
if (!(rlcP->data_plane)) {
#ifdef DEBUG_RLC_AM_SEND_CONFIRM
msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[sdu_index]->data))->mui);
#endif
rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE, rlcP->data_plane);
}
rlcP->input_sdus[sdu_index] = NULL;
rlcP->nb_sdu -= 1;
#ifdef DEBUG_RLC_AM_FREE_SDU
msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP->rb_id, sdu_index);
#endif
}
sdu_index = (sdu_index + 1) % rlcP->size_input_sdus_buffer;
}
//---------------------------------------------------------------
// here delete all PDUs up to and except the last of the last sdu discarded
sdu = rlcP->input_sdus[sdu_index];
sdu_mngt = (struct rlc_am_tx_sdu_management *) (sdu->data);
sn = rlcP->vt_a;
while (sn != sdu_mngt->last_pdu_sn) {
if ((pdu2 = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size])) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD FREE PDU SN 0x%03X\n", rlcP->rb_id, sn);
#endif
// check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((((struct rlc_am_tx_data_pdu_management *) (pdu2->data))->copy)) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] FREE PDU COPY ALSO\n", rlcP->rb_id);
#endif
list2_remove_element (((struct rlc_am_tx_data_pdu_management *) (pdu2->data))->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (((struct rlc_am_tx_data_pdu_management *) (pdu2->data))->copy);
}
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management *) (pdu2->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
free_mem_block (pdu2);
rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL;
}
sn = (sn + 1) & SN_12BITS_MASK;
}
//----------------------------------------------
// Now for the last pdu of the last sdu discarded, check if it contains other segments of
// sdu newer than the discarded
// if the pdu cannot be found : it is OK, nothing to do
pdu = rlcP->retransmission_buffer[sdu_mngt->last_pdu_sn % rlcP->recomputed_configured_tx_window_size];
if ((pdu)) {
// search the index of the sdu passed in parameter
pdu_mngt = (struct rlc_am_tx_data_pdu_management *) pdu->data;
if (pdu_mngt->sdu[pdu_mngt->nb_sdu - 1] == sdu_index) {
//----------------------------------------------
// now check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((pdu_mngt->copy)) {
list2_remove_element (pdu_mngt->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (pdu_mngt->copy);
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X\n", rlcP->rb_id, sn);
rlc_am_display_data_pdu7 (pdu);
#endif
//----------------
// discard the pdu
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management *) (pdu->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
pdu_index = pdu_mngt->sn % rlcP->recomputed_configured_tx_window_size;
free_mem_block (rlcP->retransmission_buffer[pdu_index]);
rlcP->retransmission_buffer[pdu_index] = NULL;
} else {
// if this pdu is not discarded, mark the sdu discarded by writing "-1" for their index : used in retransmission
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, CONTAINS OTHER SDUS (LAST SDU INDEX=%d): NOT CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn, pdu_mngt->sdu[pdu_mngt->nb_sdu - 1]);
#endif
sdu_index2 = 0;
while (pdu_mngt->sdu[sdu_index2] != sdu_index) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index % AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]);
#endif
pdu_mngt->sdu[sdu_index2] = -1;
sdu_index2 += 1;
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index %d AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]);
#endif
pdu_mngt->sdu[sdu_index2] = -1;
}
}
#ifdef DEBUG_RLC_AM_DISCARD
else {
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, ALREADY CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn);
}
#endif
//----------------
// discard the sdu
if ((rlcP->input_sdus[sdu_index])) { // may be removed by "free_retransmission_buffer_no_confirmation"
if (sdu_index == rlcP->current_sdu_index) {
// sdu under segmentation
rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[sdu_index]->data))->sdu_remaining_size;
((struct rlc_am_tx_sdu_management *) (rlcP->input_sdus[sdu_index]->data))->no_new_sdu_segmented_in_last_pdu = 1;
rlcP->li_exactly_filled_to_add_in_next_pdu = 0;
rlcP->li_one_byte_short_to_add_in_next_pdu = 0;
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD THE SDU DISCARDED WAS UNDER SEGMENTATION (index %d)\n", rlcP->rb_id, sdu_index);
#endif
}
list2_add_tail (rlcP->input_sdus[sdu_index], &rlcP->sdu_discarded);
#ifdef DEBUG_RLC_AM_FREE_SDU
msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP - rb_id, sdu_index);
#endif
rlcP->input_sdus[sdu_index] = NULL;
rlcP->nb_sdu -= 1;
}
}
@@ -1,49 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_notif_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__
# define __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "rlc_am_structs.h"
# include "rlc_am_constants.h"
# include "mem_block.h"
//-----------------------------------------------------------------------------
extern void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity *rlcP, mem_block_t * discard_procedureP);
extern void rlc_am_discard_check_sdu_time_out (struct rlc_am_entity *rlcP);
extern void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity *rlcP, mem_block_t * pduP);
# endif
-585
View File
@@ -1,585 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_rx.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc_am_receiver_proto_extern.h"
#include "rlc_primitives.h"
#include "rlc_am_status_proto_extern.h"
#include "rlc_am_receiver_proto_extern.h"
#include "rlc_am_discard_tx_proto_extern.h"
#include "rlc_am_discard_notif_proto_extern.h"
#include "rlc_am_retrans_proto_extern.h"
#include "rlc_am_util_proto_extern.h"
#include "rlc_am_proto_extern.h"
#include "umts_timer_struct.h"
#include "umts_timer_proto_extern.h"
#include "mem_block.h"
//-----------------------------------------------------------------------------
void rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity *rlcP);
void rlc_am_free_discard_procedure (mem_block_t * mb_current_procedureP);
inline void rlc_am_discard_free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP);
uint8_t *retransmission_buffer_management_mrw (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
uint8_t *retransmission_buffer_management_mrw_ack (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
//-----------------------------------------------------------------------------
void
rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity *rlcP)
{
//-----------------------------------------------------------------------------
mem_block_t *mb_proc;
mem_block_t *tmp_proc;
struct rlc_am_discard_procedure *procedure;
/* From 3GPP 25.322 V5.0.0 (2002-03)
The Sender shall terminate the SDU discard with explicit signalling procedure if one of the
following criteria is fulfilled:
- a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE in retransmission_buffer_management_mrw_ack(..)
field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW_SUFI,
and the N field in the received MRW_ACK SUFI is set equal to "0000";
- a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE in retransmission_buffer_management_mrw_ack(..)
field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW_SUFI,
and the N field in the received MRW_ACK SUFI is set equal to the NLENGTH field in the
transmitted MRW SUFI;
- a STATUS PDU/piggybacked STATUS PDU containing an ACK SUFI is received, and the LSN field : DONE HERE
in the received ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI.
Upon termination of the SDU discard with explicit signalling procedure, the Sender shall:
- stop the timer Timer_MRW;
- update VT(A) and VT(MS) according to the received STATUS PDU/piggybacked STATUS PDU;
The Sender shall not confirm to upper layers the SDUs that are requested to be discarded.
*/
mb_proc = rlcP->discard_procedures.head;
while ((mb_proc)) {
procedure = (struct rlc_am_discard_procedure *) (mb_proc->data);
if (rlc_am_comp_sn (rlcP, rlcP->vt_a, rlcP->vt_a, procedure->last_pdu_sn) > 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT NEW VT(A) 0x%04X REMOVE PROCEDURE SN_MRWlength 0x%04X\n", rlcP->rb_id, rlcP->vt_a, procedure->last_pdu_sn);
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ACK\n", rlcP->rb_id);
#endif
tmp_proc = mb_proc->next;
list2_remove_element (mb_proc, &rlcP->discard_procedures);
// if procedure is running, free timer resources
if ((procedure->running) && (rlcP->timer_mrw)) {
if (rlcP->timer_mrw == list2_remove_element (rlcP->timer_mrw, &rlcP->rlc_am_timer_list)) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ACK->TERMINATE PROCEDURE: REMOVE TIMER mrw id %p\n", rlcP->rb_id, ((struct timer_unit *) (rlcP->timer_mrw->data))->timer_id);
#endif
free_mem_block (rlcP->timer_mrw);
rlcP->timer_mrw = NULL;
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT REMOVE TIMER FAILED\n", rlcP->rb_id);
#endif
}
}
rlc_am_free_discard_procedure (mb_proc);
mb_proc = tmp_proc;
rlcP->vt_mrw = 0;
} else {
mb_proc = mb_proc->next;
}
}
// may be other discard procedures to run
rlc_am_schedule_procedure (rlcP);
}
//-----------------------------------------------------------------------------
void
rlc_am_free_discard_procedure (mem_block_t * mb_current_procedureP)
{
//-----------------------------------------------------------------------------
// be carefull : the timer is not free here, it should be done before
struct rlc_am_discard_procedure *procedure;
if (mb_current_procedureP) {
procedure = (struct rlc_am_discard_procedure *) (mb_current_procedureP->data);
list_free (&procedure->sdu_list);
if (procedure->control_pdu) {
free_mem_block (procedure->control_pdu);
}
free_mem_block (mb_current_procedureP);
}
}
//-----------------------------------------------------------------------------
inline void
rlc_am_discard_free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP)
{
//-----------------------------------------------------------------------------
uint16_t working_sn;
uint16_t working_sn_index; // index in buffer
// should start reassembly with sn working_sn
working_sn = rlcP->last_reassemblied_sn;
working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size;
#ifdef DEBUG_RLC_AM_DISCARD
display_receiver_buffer (rlcP);
#endif
while (working_sn != sn_mrw_iP) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER FREE RECEIVER BUFFER pdu sn 0x%04X VR(R) 0x%04X\n", rlcP->rb_id, working_sn, rlcP->vr_r);
#endif
free_receiver_buffer (rlcP, working_sn_index);
rlcP->last_reassemblied_sn = working_sn;
working_sn = (working_sn + 1) & SN_12BITS_MASK;
working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size;
}
// From 3GPP TS 25.322 V5.0.0 (2002-03) page 35
// NLENGTH is used together with SN_MRWLENGTH to indicate the end of the last SDU to be discarded in the receiver.
// NLENGTH indicates which LI in the PDU with sequence number SN_MRWLENGTH corresponds to the last SDU to be discarded in the receiver.
// NLENGTH = 0 indicates that the last SDU ended in the PDU with sequence number SN_MRWLENGTH -1 and that the first data octet
// in the PDU with sequence number SN_MRWLENGTH is the first data octet to be reassembled next.
// erase previous sdu in construction
rlcP->output_sdu_size_to_write = 0;
if ((nlengthP)) {
rlcP->discard_reassembly_after_li = nlengthP; // will be used by process_receiver_buffer
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER rlc_am_discard_free_receiver_buffer pdu sn 0x%04X (nlength=0)\n", rlcP->rb_id, working_sn);
#endif
free_receiver_buffer (rlcP, working_sn_index);
rlcP->discard_reassembly_after_li = RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0;
rlcP->last_reassemblied_sn = working_sn;
}
}
//-----------------------------------------------------------------------------
uint8_t *
retransmission_buffer_management_mrw (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP)
{
//-----------------------------------------------------------------------------
mem_block_t *mb;
uint8_t *p8;
uint16_t sn_mrw_i[15];
uint16_t new_vr_r;
uint16_t working_sn;
uint16_t working_sn_index; // index in buffer
uint8_t sn_mrw_i_index;
uint8_t mrw_length;
uint8_t nlength;
#ifdef DEBUG_RLC_AM_DISCARD
uint8_t i;
#endif
/* From 3GPP TS 25.322 V5.0.0 (2002-03)
Upon reception of the STATUS PDU/piggybacked STATUS PDU containing an MRW SUFI, the Receiver shall:
- if the LENGTH field in the received MRW SUFI is "0000":
- consider SN_MRW1 to be above or equal to VR(R).
- otherwise:
- consider SN_MRW1 to be less than VR(MR);
- consider all the SN_MRWis other than SN_MRW1 to be in sequential order within the list and
sequentially above or equal to SN_MRWi-1.
- discard AMD PDUs up to and including the PDU with sequence number SN_MRWLENGTH-1;
- if the NLENGTH field in the received MRW SUFI is "0000":
- reassemble from the first data octet of the AMD PDU with sequence number SN_MRWLENGTH
after the discard.
- otherwise:
- discard further the data octets in the AMD PDU with sequence number SN_MRWLENGTH up to and
including the octet indicated by the NLENGTH:th LI field of the PDU with sequence number
SN_MRWLENGTH;
- reassemble from the succeeding data octet in the AMD PDU with sequence number SN_MRWLENGTH
after the discard;
- if "Send MRW" is configured:
- inform upper layers about all of the discarded SDUs that were not previously delivered to
upper layer or discarded by other MRW SUFIs;
- update the state variables VR(R), VR(H) and VR(MR) according to the received
STATUS PDU/piggybacked STATUS PDU;
- assemble a MRW_ACK SUFI
- schedule and submit to lower layer a STATUS PDU/piggybacked STATUS PDU containing the MRW_ACK
SUFI.
The Receiver shall:
- set the SN_ACK field in the MRW_ACK SUFI to the new value of VR(R), updated after reception
of the MRW SUFI;
- if the SN_ACK field in the MRW_ACK SUFI is set equal to the SN_MRWLENGTH field in the
received MRW SUFI:
- set the N field in the MRW_ACK SUFI to the NLENGTH field in the received MRW SUFI.
- otherwise:
- set the N field in the MRW_ACK SUFI to "0000";
- include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted,
according to subclause 11.5.2.
*/
p8 = byte1P;
sn_mrw_i_index = 0;
if (*byte_alignedP) {
mrw_length = *p8++ & 0X0F; // number of SN_MRWi
} else {
p8 = p8 + 1;
mrw_length = (*p8 & 0XF0) >> 4; // number of SN_MRWi
}
if (!(mrw_length)) {
if (*byte_alignedP) {
// sn_mrw_i is SN_MRW length
sn_mrw_i[0] = (*p8++) << 4;
sn_mrw_i[0] += (*p8) >> 4;
*byte_alignedP = 0;
} else {
// sn_mrw_i is SN_MRW length
sn_mrw_i[0] = (*p8++) << 8;
sn_mrw_i[0] += *p8++;
nlength = (*p8 & 0xF0) >> 4;
*byte_alignedP = 1;
}
sn_mrw_i_index += 1;
} else {
// get all sn_mrw_i
while (mrw_length != sn_mrw_i_index) {
if (*byte_alignedP) {
sn_mrw_i[sn_mrw_i_index] = (*p8++) << 4;
sn_mrw_i[sn_mrw_i_index] += (*p8) >> 4;
*byte_alignedP = 0;
} else {
sn_mrw_i[sn_mrw_i_index] = ((*p8++) & 0x0F) << 8;
sn_mrw_i[sn_mrw_i_index] += (*p8++);
*byte_alignedP = 1;
}
sn_mrw_i_index += 1;
}
}
// get nlength
if (*byte_alignedP) {
nlength = (*p8 & 0xF0) >> 4;
*byte_alignedP = 0;
} else {
nlength = *p8++ & 0x0F;
*byte_alignedP = 1;
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER RECEIVED MRW LENGTH %d ", rlcP->rb_id, mrw_length);
for (i = 0; i < sn_mrw_i_index; i++) {
msg ("sn_mrw%d 0x%04X ", i + 1, sn_mrw_i[i]);
}
msg ("Nlength %d\n", nlength);
#endif
/********************************************************************
* M R W D I S C A R D E D *
********************************************************************/
/* From 3GPP TS 25.322 V5.0.0
Reception of obsolete/corrupted MRW SUFI by the Receiver
If the received MRW SUFI contains outdated information about the receiving window
(receiving window already moved further than MRW SUFI is indicating), the Receiver shall:
- discard the MRW SUFI;
- set the SN_ACK field in the MRW_ACK SUFI to the current value of VR(R);
- set the N field in the MRW_ACK SUFI to "0000";
- include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted.
*/
if (rlc_am_comp_sn (rlcP, rlcP->vr_r, sn_mrw_i[sn_mrw_i_index - 1], rlcP->vr_r) < 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER ERROR received OBSOLETE/CORRUPTED MRW command VR(R) 0x%04X VR(H) 0x%04X VR(MR) 0x%04X SN_MRWlength 0x%04X\n",
rlcP->rb_id, rlcP->vr_r, rlcP->vr_h, rlcP->vr_mr, sn_mrw_i[sn_mrw_i_index - 1]);
#endif
// send status pdu mrw_ack
if ((mb = rlc_am_create_status_pdu_mrw_ack (rlcP, 0, rlcP->vr_r))) {
list_add_tail_eurecom (mb, &rlcP->control);
}
return p8;
} else {
/********************************************************************
* M R W N O T D I S C A R D E D *
********************************************************************/
new_vr_r = sn_mrw_i[sn_mrw_i_index - 1];
/***********************************
* DISCARD PDUS IN THE RECEIVER *
***********************************/
// should start discard with sn working_sn
working_sn = rlcP->last_reassemblied_sn;
working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size;
// discard all pdus except the last one
#ifdef DEBUG_RLC_AM_DISCARD
display_receiver_buffer (rlcP);
#endif
while (working_sn != new_vr_r) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER FREE RECEIVER BUFFER pdu sn 0x%04X VR(R) 0x%04X\n", rlcP->rb_id, working_sn, rlcP->vr_r);
#endif
free_receiver_buffer (rlcP, working_sn_index);
rlcP->last_reassemblied_sn = working_sn;
working_sn = (working_sn + 1) & SN_12BITS_MASK;
working_sn_index = working_sn % rlcP->recomputed_configured_rx_window_size;
}
// From 3GPP TS 25.322 V5.0.0 (2002-03) page 35
// NLENGTH is used together with SN_MRWLENGTH to indicate the end of the last SDU to be discarded in the receiver.
// NLENGTH indicates which LI in the PDU with sequence number SN_MRWLENGTH corresponds to the last SDU to be discarded in the receiver.
// NLENGTH = 0 indicates that the last SDU ended in the PDU with sequence number SN_MRWLENGTH -1 and that the first data octet
// in the PDU with sequence number SN_MRWLENGTH is the first data octet to be reassembled next.
// erase previous sdu in construction
rlcP->output_sdu_size_to_write = 0;
rlcP->discard_reassembly_start_sn = new_vr_r;
rlcP->discard_reassembly_after_li = nlength; // will be used by process_receiver_buffer
if (rlc_am_comp_sn (rlcP, rlcP->vr_r, new_vr_r, rlcP->vr_r) > 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER... VR(R) : 0x%04X -> 0x%04X (VR(H)=0x%04X)\n", rlcP->rb_id, rlcP->vr_r, new_vr_r, rlcP->vr_h);
#endif
if (rlc_am_comp_sn (rlcP, rlcP->vr_r, new_vr_r, rlcP->vr_h) > 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD RECEIVER... VR(H) : 0x%04X -> 0x%04X\n", rlcP->rb_id, rlcP->vr_h, new_vr_r);
#endif
rlcP->vr_h = new_vr_r;
}
rlcP->vr_r = new_vr_r;
rlcP->ack.vr_r_modified = 1; // for status generation
rlcP->vr_mr = (rlcP->vr_r + rlcP->configured_rx_window_size - 1) & SN_12BITS_MASK;
}
if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON)) {
//send tu upper layers discarded sdus infos !!
// TO DO !!!!!!!!
}
if (rlcP->pdu_size <= 126) {
process_receiver_buffer_7 (rlcP);
} else {
process_receiver_buffer_15 (rlcP);
}
/* From 3GPP 25.322 V5.0.0 (2002-03)
The Receiver shall:
- set the SN_ACK field in the MRW_ACK SUFI to the new value of VR(R), updated after reception
of the MRW SUFI;
- if the SN_ACK field in the MRW_ACK SUFI is set equal to the SN_MRWLENGTH field in the
received MRW SUFI:
- set the N field in the MRW_ACK SUFI to the NLENGTH field in the received MRW SUFI.
- otherwise:
- set the N field in the MRW_ACK SUFI to "0000";
- include the MRW_ACK SUFI in the next STATUS PDU/piggybacked STATUS PDU to be transmitted,
according to subclause 11.5.2. */
if (sn_mrw_i[sn_mrw_i_index - 1] == rlcP->vr_r) {
mb = rlc_am_create_status_pdu_mrw_ack (rlcP, nlength, rlcP->vr_r);
} else {
mb = rlc_am_create_status_pdu_mrw_ack (rlcP, 0, rlcP->vr_r);
}
/* SEND STATUS PDU MRW ACK */
if (mb) {
list_add_tail_eurecom (mb, &rlcP->control);
}
return p8;
}
}
//-----------------------------------------------------------------------------
uint8_t *
retransmission_buffer_management_mrw_ack (struct rlc_am_entity * rlcP, uint8_t * byte1P, uint8_t * byte_alignedP)
{
//-----------------------------------------------------------------------------
mem_block_t *mb;
mem_block_t *mb_current_procedure;
struct rlc_am_tx_data_pdu_management *rlc_header;
struct rlc_am_discard_procedure *procedure;
uint8_t *p8;
uint16_t sn_ack;
uint16_t index;
uint8_t n; // field of mrw_ack sufi
//-------------------------------------
// DECODE SUFI MRW_ACK
//-------------------------------------
p8 = byte1P;
if (*byte_alignedP) {
n = *p8++ & 0X0F;
// sn_mrw_i is SN_MRW length
sn_ack = (*p8++) << 4;
sn_ack += (*p8) >> 4;
*byte_alignedP = 0;
} else {
p8 = p8 + 1;
n = (*p8 & 0XF0) >> 4;
// sn_mrw_i is SN_MRW length
sn_ack = ((*p8++) & 0x0F) << 8;
sn_ack += *p8++;
*byte_alignedP = 1;
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("\n[RLC_AM][RB %d] DISCARD TRANSMIT RX MRW_ACK N %d SN_ACK 0x%04X VT(A) 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, n, sn_ack, rlcP->vt_a, rlcP->vt_s);
//display_retransmission_buffer(rlcP);
#endif
// compare to current running procedure
if ((mb_current_procedure = rlcP->discard_procedures.head)) {
procedure = (struct rlc_am_discard_procedure *) (mb_current_procedure->data);
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ... procedure->last_pdu_sn 0x%04X procedure->nlength 0x%04X \n", rlcP->rb_id, procedure->last_pdu_sn, procedure->nlength);
#endif
/* From 3GPP TS 25.322 V5.0.0
The Sender shall discard the received MRW_ACK SUFI if one of the following cases occurs:
- the timer Timer_MRW is not active;
or
- the SN_ACK field in the received MRW_ACK SUFI < the SN_MRWLENGTH field in the transmitted MRW SUFI;
or
- the SN_ACK field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW SUFI,
and the N field in the received MRW_ACK SUFI is not equal to the NLENGTH field in the transmitted MRW SUFI;
or
- the SN_ACK field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI,
and the N field in the received MRW_ACK SUFI is not equal to "0000".
*/
if ((rlcP->timer_mrw == NULL) || // if timer_MRW is not active
(rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) > 0) ||
((rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) == 0) && (n != procedure->nlength)) ||
((rlc_am_comp_sn (rlcP, rlcP->vt_a, procedure->last_pdu_sn, sn_ack) < 0) && (n != 0))) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR RX OBSOLETE MRW_ACK VT(A) 0x%04X VT(S) 0x%04X SN_MRWlength 0x%04X N %d SN_ACK 0x%04X\n",
rlcP->rb_id, rlcP->vt_a, rlcP->vt_s, procedure->last_pdu_sn, n, sn_ack);
#endif
} else if (
/* From 3GPP 25.322 V5.0.0 (2002-03)
The Sender shall terminate the SDU discard with explicit signalling procedure if one of the
following criteria is fulfilled:
- a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE HERE
field in the received MRW_ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW_SUFI,
and the N field in the received MRW_ACK SUFI is set equal to "0000";
- a STATUS PDU/piggybacked STATUS PDU containing an MRW_ACK SUFI is received, and the SN_ACK : DONE HERE
field in the received MRW_ACK SUFI = the SN_MRWLENGTH field in the transmitted MRW_SUFI,
and the N field in the received MRW_ACK SUFI is set equal to the NLENGTH field in the
transmitted MRW SUFI;
- a STATUS PDU/piggybacked STATUS PDU containing an ACK SUFI is received, and the LSN field : DONE in rlc_am_received_sufi_ack_check_discard_procedures(...)
in the received ACK SUFI > the SN_MRWLENGTH field in the transmitted MRW SUFI.
Upon termination of the SDU discard with explicit signalling procedure, the Sender shall:
- stop the timer Timer_MRW;
- update VT(A) and VT(MS) according to the received STATUS PDU/piggybacked STATUS PDU;
The Sender shall not confirm to upper layers the SDUs that are requested to be discarded.
*/
(rlc_am_comp_sn (rlcP, rlcP->vt_a, sn_ack, procedure->last_pdu_sn) > 0) || ((sn_ack == procedure->last_pdu_sn) && (n == procedure->nlength))
) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD PROCEDURE %p TERMINATED\n", rlcP->rb_id, mb_current_procedure);
#endif
rlcP->vt_mrw = 0;
// remove timer
if ((rlcP->timer_mrw)) {
if (rlcP->timer_mrw == list2_remove_element (rlcP->timer_mrw, &rlcP->rlc_am_timer_list)) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT TERMINATE PROCEDURE: REMOVE TIMER mrw id %p\n", rlcP->rb_id, ((struct timer_unit *) (rlcP->timer_mrw->data))->timer_id);
#endif
free_mem_block (rlcP->timer_mrw);
rlcP->timer_mrw = NULL;
}
#ifdef DEBUG_RLC_AM_DISCARD
else {
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR TERMINATION PROCEDURE : TIMER MRW IS WRONG\n", rlcP->rb_id); // in fact : no, the lists are not protected against an element that is not inside the list
}
#endif
}
#ifdef DEBUG_RLC_AM_DISCARD
else {
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR TERMINATION PROCEDURE : NO TIMER MRW WAS FOUND\n", rlcP->rb_id);
}
#endif
mb_current_procedure = list2_remove_head (&rlcP->discard_procedures);
//update VT(A)
if (rlc_am_comp_sn (rlcP, rlcP->vt_a, sn_ack, rlcP->vt_a) > 0) {
// free resources that may be in retransmission buffer
while (rlcP->vt_a != sn_ack) {
index = rlcP->vt_a % rlcP->recomputed_configured_tx_window_size;
if ((mb = rlcP->retransmission_buffer[index])) {
rlc_header = (struct rlc_am_tx_data_pdu_management *) (mb->data);
if (rlc_header->nb_sdu > 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT CASE 1 MRW_ACK\n", rlcP->rb_id);
#endif
// the sender of MRW_ACK changed sn_mrw_length to vr_r, so it is normal to free
// pdus that are linked with sdus
free_retransmission_buffer_no_confirmation (rlcP, index);
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT CASE 2 MRW_ACK FREE REMAINING RETRANS PDU 0x%04X\n", rlcP->rb_id, rlcP->vt_a);
#endif
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (rlc_header->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
free_mem_block (mb);
rlcP->retransmission_buffer[index] = NULL;
}
}
rlcP->vt_a = (rlcP->vt_a + 1) & SN_12BITS_MASK;
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT MRW_ACK VT(A) UPDATED 0x%04X VT(S) 0x%04X\n", rlcP->rb_id, rlcP->vt_a, rlcP->vt_s);
#endif
}
rlc_am_free_discard_procedure (mb_current_procedure);
rlc_am_schedule_procedure (rlcP);
} else {
msg ("[RLC_AM][RB %d] DISCARD TRANSMIT ERROR RX MRW_ACK CASE NOT TAKEN IN ACCOUNT : NO ACTION !\n", rlcP->rb_id);
}
}
#ifdef DEBUG_RLC_AM_DISCARD
//display_mem_load();
//display_retransmission_buffer(rlcP);
#endif
return p8;
}
@@ -1,49 +0,0 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_rx_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__
# define __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mem_block.h"
//-----------------------------------------------------------------------------
extern void rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity *rlcP);
extern void rlc_am_free_discard_procedure (mem_block_t * mb_current_procedureP);
extern inline void rlc_am_discard_free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP);
extern uint8_t *retransmission_buffer_management_mrw (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
extern uint8_t *retransmission_buffer_management_mrw_ack (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
# endif

Some files were not shown because too many files have changed in this diff Show More