Merge branch 'develop' of https://gitlab.eurecom.fr/oai/openairinterface5g into mac-indentation-fix

Conflicts:
	openair2/LAYER2/MAC/config.c
	openair2/LAYER2/MAC/eNB_scheduler.c
	openair2/LAYER2/MAC/eNB_scheduler_primitives.c
This commit is contained in:
Raymond Knopp
2018-02-03 06:23:55 -08:00
317 changed files with 8892 additions and 32274 deletions
+2
View File
@@ -40,3 +40,5 @@ MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDat
MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq, rrc_mac_mcch_data_req)
MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind)
MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req)
+8
View File
@@ -43,11 +43,13 @@
#define RRC_MAC_MCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_req
#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind
#define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req
// Some constants from "LAYER2/MAC/defs.h"
#define BCCH_SDU_SIZE (512)
#define CCCH_SDU_SIZE (512)
#define MCCH_SDU_SIZE (512)
#define PCCH_SDU_SIZE (512)
//-------------------------------------------------------------------------------------------//
// Messages between RRC and MAC layers
@@ -114,4 +116,10 @@ typedef struct RrcMacMcchDataInd_s {
uint8_t mbsfn_sync_area;
} RrcMacMcchDataInd;
typedef struct RrcMacPcchDataReq_s {
uint32_t frame;
uint32_t sdu_size;
uint8_t sdu[PCCH_SDU_SIZE];
uint8_t enb_index;
} RrcMacPcchDataReq;
#endif /* MAC_MESSAGES_TYPES_H_ */
-8
View File
@@ -244,9 +244,7 @@ typedef struct {
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)
@@ -314,18 +312,12 @@ typedef struct {
#ifndef OPENAIR2_IN
#ifndef CELLULAR
//#include "L3_rrc_defs.h"
#endif
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];
#ifndef CELLULAR
// L2_ID UE_id[NB_MODULES_MAX][NB_CNX_CH];
uint8_t UE_id[NB_MODULES_MAX][NB_CNX_CH][5];
#endif
void (*openair_rrc_top_init)(void);
char (*openair_rrc_eNB_init)(uint8_t );
char (*openair_rrc_UE_init)(uint8_t, uint8_t);
-43
View File
@@ -22,12 +22,6 @@
#ifndef __openair_DEFS_H__
#define __openair_DEFS_H__
#ifndef USER_MODE
#include <linux/kernel.h>
#endif //USER_MODE
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#if !defined (msg)
@@ -49,44 +43,7 @@
#define PAGE_MASK 0xfffff000
#define virt_to_phys(x) (x)
#else // USER_MODE
#include <rtai.h>
#define msg rt_printk
#ifdef BIGPHYSAREA
#define bigmalloc(x) (bigphys_malloc(x))
#define bigmalloc16(x) (bigphys_malloc(x))
#define malloc16(x) (bigphys_malloc(x))
#define free16(y,x)
#define bigfree(y,x)
#else // BIGPHYSAREA
#define bigmalloc(x) (dma_alloc_coherent(pdev[0],(x),&dummy_dma_ptr,0))
#define bigmalloc16(x) (dma_alloc_coherent(pdev[0],(x),&dummy_dma_ptr,0))
#define bigfree(y,x) (dma_free_coherent(pdev[0],(x),(void *)(y),dummy_dma_ptr))
#define malloc16(x) (kmalloc(x,GFP_KERNEL))
#define free16(y,x) (kfree(y))
#endif // BIGPHYSAREA
#ifdef CBMIMO1
#define openair_get_mbox() (*(unsigned int *)mbox)
#else //CBMIMO1
#define openair_get_mbox() (*(unsigned int *)PHY_vars->mbox>>1)
#endif //CBMIMO1
#endif // USERMODE
// #define bzero(s,n) (memset((s),0,(n)))
#define cmax(a,b) ((a>b) ? (a) : (b))
#define cmin(a,b) ((a<b) ? (a) : (b))
#endif // /*__openair_DEFS_H__ */
-39
View File
@@ -1,39 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __openair_TYPES_H__
#define __openair_TYPES_H__
//#ifdef USER_MODE
//#include <stdint.h>
//typedef int8_t s8; /* 8 bit signed integer */
//typedef int16_t s16; /* 16 bit signed integer */
//typedef int32_t s32; /* 32 bit signed integer */
//typedef int64_t s64; /* 64 bit signed integer */
//typedef uint8_t u8; /* 8 bit unsigned integer */
//typedef uint16_t u16; /* 16 bit unsigned integer */
//typedef uint32_t u32; /* 32 bit unsigned integer */
//typedef uint64_t u64; /* 64 bit unsigned integer */
//#else
//#include <linux/types.h>
//#endif
#endif /*__openair_TYPES_H__ */
+1
View File
@@ -30,3 +30,4 @@
// Messages between RRC and PDCP layers
MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req)
MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind)
MESSAGE_DEF(RRC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq, rrc_pcch_data_req)
+10
View File
@@ -33,6 +33,7 @@
// Defines to access message fields.
#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_req
#define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_ind
#define RRC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_pcch_data_req
//-------------------------------------------------------------------------------------------//
// Messages between RRC and PDCP layers
@@ -60,4 +61,13 @@ typedef struct RrcDcchDataInd_s {
uint8_t eNB_index; // LG: needed in UE
} RrcDcchDataInd;
typedef struct RrcPcchDataReq_s {
uint32_t sdu_size;
uint8_t *sdu_p;
uint8_t mode;
uint16_t rnti;
uint8_t ue_index;
uint8_t CC_id;
} RrcPcchDataReq;
#endif /* PDCP_MESSAGES_TYPES_H_ */
-8
View File
@@ -43,7 +43,6 @@
#define NL_MAX_PAYLOAD 9000 /* this should cover the max mtu size*/
#endif
#ifdef USER_MODE
#ifdef LARGE_SCALE
# define NB_MODULES_MAX 128
# define NB_NODE_MAX 128
@@ -51,11 +50,6 @@
# define NB_MODULES_MAX 32
# define NB_NODE_MAX 32
#endif
#else
# define NB_MODULES_MAX 1
# define NB_NODE_MAX 1
#endif //PHY_EMUL
#ifdef JUMBO_FRAME
# define MAX_IP_PACKET_SIZE 10000 // 9000
@@ -132,9 +126,7 @@
#define UNUSED_PARAM_MBMS_SESSION_ID 0
#define UNUSED_PARAM_MBMS_SERVICE_ID 0
#ifdef USER_MODE
#define printk printf
#endif
#define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE)
+1 -25
View File
@@ -30,7 +30,7 @@
#ifndef __PLATFORM_TYPES_H__
# define __PLATFORM_TYPES_H__
#ifdef USER_MODE
#if !defined(NAS_NETLINK)
#include <stdint.h>
#endif
@@ -271,29 +271,5 @@ typedef struct protocol_ctxt_s {
(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
+9 -41
View File
@@ -20,45 +20,13 @@
*/
#ifndef _RTOS_HEADER_H_
# define _RTOS_HEADER_H_
# if defined(RTAI) && !defined(USER_MODE)
// CONVERSION BETWEEN POSIX PTHREAD AND RTAI FUNCTIONS
/*
# define pthread_mutex_init pthread_mutex_init_rt
# define pthread_mutexattr_init pthread_mutexattr_init_rt
# define pthread_mutex_lock pthread_mutex_lock_rt
# define pthread_mutex_unlock pthread_mutex_unlock_rt
# define pthread_mutex_destroy pthread_mutex_destroy_rt
# define pthread_cond_init pthread_cond_init_rt
# define pthread_cond_wait pthread_cond_wait_rt
# define pthread_cond_signal pthread_cond_signal_rt
# define pthread_cond_destroy pthread_cond_destroy_rt
# define pthread_attr_init pthread_attr_init_rt
# define pthread_attr_setschedparam pthread_attr_setschedparam_rt
# define pthread_create pthread_create_rt
# define pthread_cancel pthread_cancel_rt
# define pthread_delete_np pthread_cancel_rt
# define pthread_attr_setstacksize pthread_attr_setstacksize_rt
# define pthread_self rt_whoami
*/
# include <asm/rtai.h>
# include <rtai.h>
# include <rtai_posix.h>
# include <rtai_fifos.h>
# include <rtai_sched.h>
# ifdef CONFIG_PROC_FS
# include <rtai_proc_fs.h>
# endif
# else
# ifdef USER_MODE
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <math.h>
# include <pthread.h>
# include <assert.h>
# define rtf_get read
# define rtf_put write
# endif
# endif
#define _RTOS_HEADER_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <pthread.h>
#include <assert.h>
#define rtf_get read
#define rtf_put write
#endif
+9
View File
@@ -33,6 +33,11 @@ MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG, MESSAGE_PRIORITY_MED, IttiMsgT
MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_context_release_log)
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_setup_request_log)
MESSAGE_DEF(S1AP_E_RAB_SETUP_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_setup_response_log)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_modify_request_log)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_modify_response_log)
MESSAGE_DEF(S1AP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_paging_log)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_request_log)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_response_log)
/* eNB application layer -> S1AP messages */
MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req)
@@ -54,6 +59,8 @@ MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_
MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_fail_t , s1ap_ue_ctxt_modification_fail)
MESSAGE_DEF(S1AP_E_RAB_SETUP_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_resp_t , s1ap_e_rab_setup_resp)
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_fail_t , s1ap_e_rab_setup_request_fail)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_resp_t , s1ap_e_rab_modify_resp)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp)
/* S1AP -> RRC messages */
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
@@ -61,6 +68,8 @@ MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_initial_
MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_req_t , s1ap_ue_ctxt_modification_req)
MESSAGE_DEF(S1AP_PAGING_IND , MESSAGE_PRIORITY_MED, s1ap_paging_ind_t , s1ap_paging_ind )
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_t , s1ap_e_rab_setup_req )
MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQ , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_req_t , s1ap_e_rab_modify_req )
MESSAGE_DEF(S1AP_E_RAB_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_command_t , s1ap_e_rab_release_command)
MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, s1ap_ue_release_command_t , s1ap_ue_release_command)
/* S1AP <-> RRC messages (can be initiated either by MME or eNB) */
+118 -12
View File
@@ -41,6 +41,7 @@
#define S1AP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_ctxt_modification_fail
#define S1AP_E_RAB_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_resp
#define S1AP_E_RAB_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req_fail
#define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
@@ -48,9 +49,12 @@
#define S1AP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_command
#define S1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_complete
#define S1AP_E_RAB_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req
#define S1AP_PAGIND_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_paging_ind
#define S1AP_E_RAB_MODIFY_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_req
#define S1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_paging_ind
#define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_req
#define S1AP_E_RAB_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_release_command
#define S1AP_E_RAB_RELEASE_RESPONSE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_release_resp
//-------------------------------------------------------------------------------------------//
/* Maximum number of e-rabs to be setup/deleted in a single message.
@@ -175,6 +179,11 @@ typedef struct s1ap_gummei_s {
uint16_t mme_group_id;
} s1ap_gummei_t;
typedef struct s1ap_imsi_s {
uint8_t buffer[S1AP_IMSI_LENGTH];
uint8_t length;
} s1ap_imsi_t;
typedef struct s_tmsi_s {
uint8_t mme_code;
uint32_t m_tmsi;
@@ -189,7 +198,7 @@ typedef enum ue_paging_identity_presenceMask_e {
typedef struct ue_paging_identity_s {
ue_paging_identity_presenceMask_t presenceMask;
union {
char imsi[S1AP_IMSI_LENGTH];
s1ap_imsi_t imsi;
s_tmsi_t s_tmsi;
} choice;
} ue_paging_identity_t;
@@ -260,11 +269,29 @@ typedef struct e_rab_setup_s {
uint32_t gtp_teid;
} e_rab_setup_t;
typedef struct e_rab_modify_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
} e_rab_modify_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_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;
s1ap_Cause_t cause;
uint8_t cause_value;
} e_rab_failed_t;
typedef enum s1ap_ue_ctxt_modification_present_s {
@@ -460,6 +487,12 @@ typedef struct s1ap_initial_context_setup_req_s {
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
} s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
} plmn_identity_t;
typedef struct s1ap_paging_ind_s {
/* UE identity index value.
* Specified in 3GPP TS 36.304
@@ -472,6 +505,15 @@ typedef struct s1ap_paging_ind_s {
/* Indicates origin of paging */
cn_domain_t cn_domain;
/* PLMN_identity in TAI of Paging*/
plmn_identity_t plmn_identity[256];
/* TAC in TAIList of Paging*/
int16_t tac[256];
/* size of TAIList*/
int16_t tai_size;
/* Optional fields */
paging_drx_t paging_drx;
@@ -520,16 +562,6 @@ typedef struct s1ap_ue_release_command_s {
//-------------------------------------------------------------------------------------------//
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_t;
// S1AP <-- RRC messages
typedef struct s1ap_ue_release_req_s {
unsigned eNB_ue_s1ap_id:24;
@@ -537,4 +569,78 @@ typedef struct s1ap_ue_release_req_s {
long cause_value;
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
typedef struct s1ap_e_rab_modify_req_s {
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab to be modify in the list */
uint8_t nb_e_rabs_tomodify;
/* E RAB modify request */
e_rab_t e_rab_modify_params[S1AP_MAX_E_RAB];
} s1ap_e_rab_modify_req_t;
typedef struct s1ap_e_rab_modify_resp_s {
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab modify-ed in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab modify-ed by RRC layers */
e_rab_modify_t e_rabs[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be modify in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be modify */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
} s1ap_e_rab_modify_resp_t;
typedef struct e_rab_release_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
} e_rab_release_t;
typedef struct s1ap_e_rab_release_command_s {
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
nas_pdu_t nas_pdu;
/* Number of e_rab to be released in the list */
uint8_t nb_e_rabs_torelease;
/* E RAB release command */
e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB];
} s1ap_e_rab_release_command_t;
typedef struct s1ap_e_rab_release_resp_s {
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab released in the list */
uint8_t nb_of_e_rabs_released;
/* list of e_rabs released */
e_rab_release_t e_rab_release[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be released in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be released */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
} s1ap_e_rab_release_resp_t;
#endif /* S1AP_MESSAGES_TYPES_H_ */
-30
View File
@@ -36,10 +36,6 @@
#include "common/ran_context.h"
#include "log.h"
#if defined(OAI_EMU)
# include "OCG.h"
# include "OCG_extern.h"
#endif
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
@@ -215,9 +211,6 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//,
uint32_t register_enb_pending = 0;
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
{
s1ap_register_enb_req_t *s1ap_register_eNB;
@@ -314,19 +307,6 @@ void *eNB_app_task(void *args_p)
if (RC.nb_L1_inst>0) AssertFatal(l1_north_init_eNB()==0,"could not initialize L1 north interface\n");
# if defined(ENABLE_ITTI)
# 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;
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
AssertFatal (enb_nb <= RC.nb_inst,
"Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
enb_nb, RC.nb_inst);
@@ -402,16 +382,6 @@ void *eNB_app_task(void *args_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;
-136
View File
@@ -36,10 +36,6 @@
#include "enb_config.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_externs.h"
#if defined(OAI_EMU)
# include "OCG.h"
# include "OCG_extern.h"
#endif
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
# if defined(ENABLE_USE_MME)
@@ -102,138 +98,6 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP,
return errors;
}
/* --------------------------------------------------------*/
/* from here function to use configuration module */
void RCconfig_RU(void) {
int j = 0;
int i = 0;
paramdef_t RUParams[] = RUPARAMS_DESC;
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);
if ( RUParamList.numelt > 0) {
RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*));
RC.ru_mask=(1<<NB_RU) - 1;
printf("Set RU mask to %lx\n",RC.ru_mask);
for (j = 0; j < RC.nb_RU; j++) {
RC.ru[j] = (RU_t*)malloc(sizeof(RU_t));
memset((void*)RC.ru[j],0,sizeof(RU_t));
RC.ru[j]->idx = j;
printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
RC.ru[j]->if_timing = synch_to_ext_device;
if (RC.nb_L1_inst >0)
RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
else
RC.ru[j]->num_eNB = 0;
for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = eNodeB_3GPP;
printf("Setting function for RU %d to eNodeB_3GPP\n",j);
}
else {
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
}
}
RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
for (i=0;i<RC.ru[j]->num_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
} //strcmp(local_rf, "yes") == 0
else {
printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->if_timing = synch_to_other;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS;
}
RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
} /* strcmp(local_rf, "yes") != 0 */
RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
}// j=0..num_rus
} else {
RC.nb_RU = 0;
} // setting != NULL
return;
}
void RCconfig_L1(void) {
int i,j;
paramdef_t L1_Params[] = L1PARAMS_DESC;
+145 -727
View File
@@ -61,45 +61,9 @@ extern RAN_CONTEXT_t RC;
extern int l2_init_eNB(void);
extern void mac_top_init_eNB(void);
extern void mac_init_cell_params(int Mod_idP,int CC_idP);
extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
extern uint8_t nfapi_mode;
/* sec 5.9, 36.321: MAC Reset Procedure */
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
// PHY changes for UE MAC reset
phy_reset_ue(module_idP, 0, eNB_index);
// notify RRC to relase PUCCH/SRS
// cancel all pending SRs
UE_mac_inst[module_idP].scheduling_info.SR_pending = 0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0;
//Set BSR Trigger Bmp and remove timer flags
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
// stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check!
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure
}
int32_t **rxdata;
int32_t **txdata;
@@ -303,11 +267,10 @@ void config_mib(int Mod_idP,
cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG;
cfg->num_tlv++;
#endif
LOG_I(MAC,
"%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d"
#ifdef Rel14
" PBCH repetition %d"
#endif
"\n"
@@ -328,12 +291,12 @@ void config_mib(int Mod_idP,
,cfg->emtc_config.pbch_repetitions_enable_r13.value
#endif
);
}
void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP)
{
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
if (tdd_ConfigP) { //TDD
@@ -469,219 +432,155 @@ config_sib2(int Mod_idP,
cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG;
cfg->num_tlv++;
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) {
cfg->srs_config.max_up_pts.value = 1;
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower;
cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value +
power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex;
cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag;
cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset;
cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode;
cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB;
cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset;
cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift;
cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI;
cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN;
cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN;
if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1;
else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2;
else // No hopping
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0;
cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH;
cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift;
// how to enable/disable SRS?
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present == SoundingRS_UL_ConfigCommon_PR_setup) {
cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
cfg->srs_config.max_up_pts.value = 1;
else
cfg->srs_config.max_up_pts.value = 0;
}
else {
cfg->srs_config.max_up_pts.value = 0;
}
cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG;
cfg->num_tlv++;
}
#ifdef Rel14
if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13>0) {
AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n");
AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n");
cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG;
cfg->num_tlv++;
if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) {
AssertFatal(radioResourceConfigCommon_BRP != NULL,
"radioResource rou is missing\n");
AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL,
"ext4 is missing\n");
cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag;
cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag;
cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG;
cfg->num_tlv++;
struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310;
struct PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
PRACH_ParametersCE_r13_t *p;
cfg->emtc_config.prach_ce_level_0_enable.value=0;
cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_1_enable.value=0;
cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_2_enable.value=0;
cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_3_enable.value=0;
cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_enable.value = 0;
cfg->emtc_config.prach_ce_level_1_enable.value = 0;
cfg->emtc_config.prach_ce_level_2_enable.value = 0;
cfg->emtc_config.prach_ce_level_3_enable.value = 0;
switch (prach_ParametersListCE_r13->list.count) {
case 4:
p=prach_ParametersListCE_r13->list.array[3];
cfg->emtc_config.prach_ce_level_3_enable.value = 1;
cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG;
cfg->num_tlv++;
p = prach_ParametersListCE_r13->list.array[3];
cfg->emtc_config.prach_ce_level_3_enable.value = 1;
cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13;
cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
cfg->num_tlv++;
if (p->prach_StartingSubframe_r13) {
if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG;
cfg->num_tlv++;
}
cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6;
cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6;
case 3:
p=prach_ParametersListCE_r13->list.array[2];
cfg->emtc_config.prach_ce_level_2_enable.value = 1;
cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG;
cfg->num_tlv++;
p = prach_ParametersListCE_r13->list.array[2];
cfg->emtc_config.prach_ce_level_2_enable.value = 1;
cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13;
cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
cfg->num_tlv++;
if (p->prach_StartingSubframe_r13) {
if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG;
cfg->num_tlv++;
}
cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6;
cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6;
case 2:
p=prach_ParametersListCE_r13->list.array[1];
cfg->emtc_config.prach_ce_level_1_enable.value = 1;
cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG;
cfg->num_tlv++;
p = prach_ParametersListCE_r13->list.array[1];
cfg->emtc_config.prach_ce_level_1_enable.value = 1;
cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13;
cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
cfg->num_tlv++;
if (p->prach_StartingSubframe_r13) {
if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG;
cfg->num_tlv++;
}
cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6;
cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6;
case 1:
p=prach_ParametersListCE_r13->list.array[0];
p = prach_ParametersListCE_r13->list.array[0];
cfg->emtc_config.prach_ce_level_0_enable.value = 1;
cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13;
cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
cfg->num_tlv++;
if (p->prach_StartingSubframe_r13) {
if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG;
cfg->num_tlv++;
}
cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6;
cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG;
cfg->num_tlv++;
cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6;
}
struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13;
if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG;
cfg->num_tlv++;
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG;
cfg->num_tlv++;
break;
if ((ext4_freqHoppingParameters)&&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13))
{
switch (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
choice.interval_FDD_r13;
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13:
cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodea.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
choice.interval_TDD_r13;
break;
}
}
}
if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG;
cfg->num_tlv++;
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG;
cfg->num_tlv++;
break;
if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13))
{
switch
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13:
cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodeb.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
choice.interval_FDD_r13;
break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13:
cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodeb.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
choice.interval_TDD_r13;
break;
}
}
}
}
#endif
@@ -704,6 +603,7 @@ config_dedicated_scell(int Mod_idP,
}
int
rrc_mac_config_req_eNB(module_id_t Mod_idP,
int CC_idP,
@@ -757,14 +657,12 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
int UE_id = -1;
eNB_MAC_INST *eNB = RC.mac[Mod_idP];
UE_list_t *UE_list= &eNB->UE_list;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
LOG_E(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib);
if (mib != NULL) {
if (RC.mac == NULL)
l2_init_eNB();
@@ -876,6 +774,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
NULL, ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
}
} // mib != NULL
@@ -964,16 +863,16 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
}
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, "[CONFIG] Number of PMCH in this MBSFN Area %d\n",
pmch_InfoList->list.count);
for (i = 0; i < pmch_InfoList->list.count; i++) {
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] =
&pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC,
"[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n",
i,
@@ -986,7 +885,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i,
RC.mac[Mod_idP]->common_channels[0].
pmch_Config[i]->dataMCS_r9);
// MBMS session info list in each MCH
RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] =
&pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
@@ -995,516 +894,35 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
mbms_SessionList[i]->list.count);
}
}
}
#endif
LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req);
LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req);
// if in nFAPI mode
if (
(nfapi_mode == 1 || nfapi_mode == 2) &&
(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL)
) {
while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) {
// DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
}
}
// if in nFAPI mode
if (
(nfapi_mode == 1 || nfapi_mode == 2) &&
(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL)
) {
while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) {
// DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
}
}
if (radioResourceConfigCommon != NULL) {
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = CC_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP];
if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
}
return(0);
if (radioResourceConfigCommon != NULL) {
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = CC_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP];
if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
}
return(0);
}
int
rrc_mac_config_req_ue(module_id_t Mod_idP,
int CC_idP,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon,
struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14)
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
#if defined(Rel10) || defined(Rel14)
, 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
#endif
)
{
int i;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",
Mod_idP, eNB_index);
if (tdd_Config != NULL) {
UE_mac_inst[Mod_idP].tdd_Config = tdd_Config;
}
if (tdd_Config && SIwindowsize && SIperiod) {
phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config,
*SIwindowsize, *SIperiod);
}
if (radioResourceConfigCommon != NULL) {
UE_mac_inst[Mod_idP].radioResourceConfigCommon =
radioResourceConfigCommon;
phy_config_sib2_ue(Mod_idP, 0, eNB_index,
radioResourceConfigCommon, ul_CarrierFreq,
ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig != NULL) {
LOG_I(MAC,
"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",
Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] =
logicalChannelConfig;
UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid
AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL,
"[UE %d] LCID %ld NULL ul_SpecificParameters\n",
Mod_idP, logicalChannelIdentity);
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
if (logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] =
*logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup;
LOG_D(MAC,
"[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n",
Mod_idP, logicalChannelIdentity,
*logicalChannelConfig->
ul_SpecificParameters->logicalChannelGroup);
} else {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] = MAX_NUM_LCGID;
}
UE_mac_inst[Mod_idP].
scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
}
if (mac_MainConfig != NULL) {
LOG_I(MAC,
"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",
Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].macConfig = mac_MainConfig;
UE_mac_inst[Mod_idP].measGapConfig = measGapConfig;
if (mac_MainConfig->ul_SCH_Config) {
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
(uint16_t) *
mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
} else {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
#ifndef Rel14
(uint16_t)
MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity
#else
(uint16_t) PeriodicBSR_Timer_r12_infinity;
#endif
;
}
if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
} else {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
}
phy_config_harq_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].
scheduling_info.maxHARQ_Tx);
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) mac_MainConfig->ul_SCH_Config->
retxBSR_Timer;
} else {
#ifndef Rel14
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
#else
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) RetxBSR_Timer_r12_sf2560;
#endif
}
}
#if defined(Rel10) || defined(Rel14)
if (mac_MainConfig->ext1
&& mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer =
(uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} else {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0;
}
if (mac_MainConfig->ext2
&& mac_MainConfig->ext2->mac_MainConfig_v1020) {
if (mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 =
(uint16_t) *
mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 = (uint16_t) 0;
}
if (mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) *
mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
}
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 =
(uint16_t) 0;
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
}
#endif
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
UE_mac_inst[Mod_idP].scheduling_info.drx_config =
mac_MainConfig->drx_Config;
UE_mac_inst[Mod_idP].scheduling_info.phr_config =
mac_MainConfig->phr_Config;
if (mac_MainConfig->phr_Config) {
UE_mac_inst[Mod_idP].PHR_state =
mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_idP].PHR_reconfigured = 1;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange;
} else {
UE_mac_inst[Mod_idP].PHR_reconfigured = 0;
UE_mac_inst[Mod_idP].PHR_state =
MAC_MainConfig__phr_Config_PR_setup;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
}
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF =
get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].
scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF =
get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].
scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db =
get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].
scheduling_info.PathlossChange);
UE_mac_inst[Mod_idP].PHR_reporting_active = 0;
LOG_D(MAC,
"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP,
(mac_MainConfig->phr_Config) ? mac_MainConfig->
phr_Config->present : -1,
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db);
}
if (physicalConfigDedicated != NULL) {
phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
physicalConfigDedicated);
UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc
}
#if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) {
phy_config_dedicated_scell_ue(Mod_idP, eNB_index,
sCellToAddMod_r10, 1);
UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0
}
#endif
if (measObj != NULL) {
if (measObj[0] != NULL) {
UE_mac_inst[Mod_idP].n_adj_cells =
measObj[0]->measObject.choice.
measObjectEUTRA.cellsToAddModList->list.count;
LOG_I(MAC, "Number of adjacent cells %d\n",
UE_mac_inst[Mod_idP].n_adj_cells);
for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) {
UE_mac_inst[Mod_idP].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_idP].adj_cell_id[i]);
}
phy_config_meas_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].n_adj_cells,
UE_mac_inst[Mod_idP].adj_cell_id);
}
}
if (mobilityControlInfo != NULL) {
LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",
Mod_idP, eNB_index);
ue_mac_reset(Mod_idP, eNB_index);
if (mobilityControlInfo->radioResourceConfigCommon.
rach_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
rach_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *) &UE_mac_inst[Mod_idP].
radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *) mobilityControlInfo->
radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_idP].radioResourceConfigCommon->
prach_Config.rootSequenceIndex =
mobilityControlInfo->radioResourceConfigCommon.
prach_Config.rootSequenceIndex;
if (mobilityControlInfo->radioResourceConfigCommon.
pdsch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].
radioResourceConfigCommon->pusch_ConfigCommon,
(void *) &mobilityControlInfo->
radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if (mobilityControlInfo->radioResourceConfigCommon.
pucch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pucch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if (mobilityControlInfo->
radioResourceConfigCommon.soundingRS_UL_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].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_idP].tdd_Config =
mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if (mobilityControlInfo->
radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti;
UE_mac_inst[Mod_idP].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_idP,
UE_mac_inst[Mod_idP].crnti, eNB_index);
UE_mac_inst[Mod_idP].rach_ConfigDedicated =
malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated));
if (mobilityControlInfo->rach_ConfigDedicated) {
memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated,
(void *) mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
}
phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo,
0);
}
if (mbsfn_SubframeConfigList != NULL) {
LOG_I(MAC,
"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
UE_mac_inst[Mod_idP].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_idP, i);
UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] =
mbsfn_SubframeConfigList->list.array[i];
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP,
// UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
}
#if defined(Rel10) || defined(Rel14)
if (mbsfn_AreaInfoList != NULL) {
LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n",
Mod_idP, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_idP].num_active_mbsfn_area =
mbsfn_AreaInfoList->list.count;
for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] =
mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,
"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_RepetitionPeriod_r9);
phy_config_sib13_ue(Mod_idP, 0, eNB_index, i,
UE_mac_inst[Mod_idP].
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, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",
Mod_idP);
for (i = 0; i < pmch_InfoList->list.count; i++) {
UE_mac_inst[Mod_idP].pmch_Config[i] =
&pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].
pmch_Config[i]->mch_SchedulingPeriod_r9);
}
UE_mac_inst[Mod_idP].mcch_status = 1;
}
#endif
#ifdef CBA
if (cba_rnti) {
UE_mac_inst[Mod_idP].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_idP, Mod_idP % num_active_cba_groups, cba_rnti,
eNB_index, num_active_cba_groups);
phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index,
cba_rnti, num_active_cba_groups - 1,
num_active_cba_groups);
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
return (0);
}
+584
View File
@@ -0,0 +1,584 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file config.c
* \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 0.1
* \email: navid.nikaein@eurecom.fr
* @ingroup _mac
*/
#include "COMMON/platform_types.h"
#include "COMMON/platform_constants.h"
#include "SCHED/defs.h"
#include "SystemInformationBlockType2.h"
//#include "RadioResourceConfigCommonSIB.h"
#include "RadioResourceConfigDedicated.h"
#ifdef Rel14
#include "PRACH-ConfigSIB-v1310.h"
#endif
#include "MeasGapConfig.h"
#include "MeasObjectToAddModList.h"
#include "TDD-Config.h"
#include "MAC-MainConfig.h"
#include "defs.h"
#include "proto.h"
#include "extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "common/ran_context.h"
#if defined(Rel10) || defined(Rel14)
#include "MBSFN-AreaInfoList-r9.h"
#include "MBSFN-AreaInfo-r9.h"
#include "MBSFN-SubframeConfigList.h"
#include "PMCH-InfoList-r9.h"
#endif
extern void mac_init_cell_params(int Mod_idP,int CC_idP);
extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
/* sec 5.9, 36.321: MAC Reset Procedure */
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
// PHY changes for UE MAC reset
phy_reset_ue(module_idP, 0, eNB_index);
// notify RRC to relase PUCCH/SRS
// cancel all pending SRs
UE_mac_inst[module_idP].scheduling_info.SR_pending = 0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0;
//Set BSR Trigger Bmp and remove timer flags
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
// stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check!
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure
}
int32_t **rxdata;
int32_t **txdata;
int
rrc_mac_config_req_ue(module_id_t Mod_idP,
int CC_idP,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon,
struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14)
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
#if defined(Rel10) || defined(Rel14)
, 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
#endif
)
{
int i;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",
Mod_idP, eNB_index);
if (tdd_Config != NULL) {
UE_mac_inst[Mod_idP].tdd_Config = tdd_Config;
}
if (tdd_Config && SIwindowsize && SIperiod) {
phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config,
*SIwindowsize, *SIperiod);
}
if (radioResourceConfigCommon != NULL) {
UE_mac_inst[Mod_idP].radioResourceConfigCommon =
radioResourceConfigCommon;
phy_config_sib2_ue(Mod_idP, 0, eNB_index,
radioResourceConfigCommon, ul_CarrierFreq,
ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig != NULL) {
LOG_I(MAC,
"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",
Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] =
logicalChannelConfig;
UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid
AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL,
"[UE %d] LCID %ld NULL ul_SpecificParameters\n",
Mod_idP, logicalChannelIdentity);
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
if (logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] =
*logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup;
LOG_D(MAC,
"[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n",
Mod_idP, logicalChannelIdentity,
*logicalChannelConfig->
ul_SpecificParameters->logicalChannelGroup);
} else {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] = MAX_NUM_LCGID;
}
UE_mac_inst[Mod_idP].
scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
}
if (mac_MainConfig != NULL) {
LOG_I(MAC,
"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",
Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].macConfig = mac_MainConfig;
UE_mac_inst[Mod_idP].measGapConfig = measGapConfig;
if (mac_MainConfig->ul_SCH_Config) {
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
(uint16_t) *
mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
} else {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
#ifndef Rel14
(uint16_t)
MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity
#else
(uint16_t) PeriodicBSR_Timer_r12_infinity;
#endif
;
}
if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
} else {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
}
phy_config_harq_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].
scheduling_info.maxHARQ_Tx);
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) mac_MainConfig->ul_SCH_Config->
retxBSR_Timer;
} else {
#ifndef Rel14
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
#else
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) RetxBSR_Timer_r12_sf2560;
#endif
}
}
#if defined(Rel10) || defined(Rel14)
if (mac_MainConfig->ext1
&& mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer =
(uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} else {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0;
}
if (mac_MainConfig->ext2
&& mac_MainConfig->ext2->mac_MainConfig_v1020) {
if (mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 =
(uint16_t) *
mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 = (uint16_t) 0;
}
if (mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) *
mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
}
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 =
(uint16_t) 0;
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
}
#endif
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
UE_mac_inst[Mod_idP].scheduling_info.drx_config =
mac_MainConfig->drx_Config;
UE_mac_inst[Mod_idP].scheduling_info.phr_config =
mac_MainConfig->phr_Config;
if (mac_MainConfig->phr_Config) {
UE_mac_inst[Mod_idP].PHR_state =
mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_idP].PHR_reconfigured = 1;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange;
} else {
UE_mac_inst[Mod_idP].PHR_reconfigured = 0;
UE_mac_inst[Mod_idP].PHR_state =
MAC_MainConfig__phr_Config_PR_setup;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
}
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF =
get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].
scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF =
get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].
scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db =
get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].
scheduling_info.PathlossChange);
UE_mac_inst[Mod_idP].PHR_reporting_active = 0;
LOG_D(MAC,
"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP,
(mac_MainConfig->phr_Config) ? mac_MainConfig->
phr_Config->present : -1,
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db);
}
if (physicalConfigDedicated != NULL) {
phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
physicalConfigDedicated);
UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc
}
#if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) {
phy_config_dedicated_scell_ue(Mod_idP, eNB_index,
sCellToAddMod_r10, 1);
UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0
}
#endif
if (measObj != NULL) {
if (measObj[0] != NULL) {
UE_mac_inst[Mod_idP].n_adj_cells =
measObj[0]->measObject.choice.
measObjectEUTRA.cellsToAddModList->list.count;
LOG_I(MAC, "Number of adjacent cells %d\n",
UE_mac_inst[Mod_idP].n_adj_cells);
for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) {
UE_mac_inst[Mod_idP].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_idP].adj_cell_id[i]);
}
phy_config_meas_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].n_adj_cells,
UE_mac_inst[Mod_idP].adj_cell_id);
}
}
if (mobilityControlInfo != NULL) {
LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",
Mod_idP, eNB_index);
ue_mac_reset(Mod_idP, eNB_index);
if (mobilityControlInfo->radioResourceConfigCommon.
rach_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
rach_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *) &UE_mac_inst[Mod_idP].
radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *) mobilityControlInfo->
radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_idP].radioResourceConfigCommon->
prach_Config.rootSequenceIndex =
mobilityControlInfo->radioResourceConfigCommon.
prach_Config.rootSequenceIndex;
if (mobilityControlInfo->radioResourceConfigCommon.
pdsch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].
radioResourceConfigCommon->pusch_ConfigCommon,
(void *) &mobilityControlInfo->
radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if (mobilityControlInfo->radioResourceConfigCommon.
pucch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pucch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if (mobilityControlInfo->
radioResourceConfigCommon.soundingRS_UL_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].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_idP].tdd_Config =
mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if (mobilityControlInfo->
radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)
&UE_mac_inst[Mod_idP].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_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti;
UE_mac_inst[Mod_idP].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_idP,
UE_mac_inst[Mod_idP].crnti, eNB_index);
UE_mac_inst[Mod_idP].rach_ConfigDedicated =
malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated));
if (mobilityControlInfo->rach_ConfigDedicated) {
memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated,
(void *) mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
}
phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo,
0);
}
if (mbsfn_SubframeConfigList != NULL) {
LOG_I(MAC,
"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
UE_mac_inst[Mod_idP].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_idP, i);
UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] =
mbsfn_SubframeConfigList->list.array[i];
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP,
// UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
}
#if defined(Rel10) || defined(Rel14)
if (mbsfn_AreaInfoList != NULL) {
LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n",
Mod_idP, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_idP].num_active_mbsfn_area =
mbsfn_AreaInfoList->list.count;
for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] =
mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,
"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_RepetitionPeriod_r9);
phy_config_sib13_ue(Mod_idP, 0, eNB_index, i,
UE_mac_inst[Mod_idP].
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, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",
Mod_idP);
for (i = 0; i < pmch_InfoList->list.count; i++) {
UE_mac_inst[Mod_idP].pmch_Config[i] =
&pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].
pmch_Config[i]->mch_SchedulingPeriod_r9);
}
UE_mac_inst[Mod_idP].mcch_status = 1;
}
#endif
#ifdef CBA
if (cba_rnti) {
UE_mac_inst[Mod_idP].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_idP, Mod_idP % num_active_cba_groups, cba_rnti,
eNB_index, num_active_cba_groups);
phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index,
cba_rnti, num_active_cba_groups - 1,
num_active_cba_groups);
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
return (0);
}
+20 -8
View File
@@ -39,15 +39,9 @@
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
//#include "COMMON/openair_defs.h"
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/defs.h"
@@ -109,9 +103,7 @@
//#define MCH_PAYLOAD_SIZE_MAX 16384// this value is using in case mcs and TBS index are high
#endif
#ifdef USER_MODE
#define printk printf
#endif //USER_MODE
/*!\brief Maximum number of logical channl group IDs */
#define MAX_NUM_LCGID 4
@@ -163,6 +155,8 @@
/*!\brief maximum number of slices / groups */
#define MAX_NUM_SLICES 4
#define U_PLANE_INACTIVITY_VALUE 6000
/*
* eNB part
*/
@@ -472,6 +466,15 @@ typedef struct {
/// BCCH MCS
uint32_t ccch_mcs;
/// num PCCH PDU per CC
uint32_t total_num_pcch_pdu;
/// PCCH buffer size
uint32_t pcch_buffer;
/// total PCCH buffer size
uint32_t total_pcch_buffer;
/// BCCH MCS
uint32_t pcch_mcs;
/// num active users
uint16_t num_dlactive_UEs;
/// available number of PRBs for a give SF
@@ -824,6 +827,8 @@ typedef struct {
int32_t cqi_req_timer;
int32_t ul_inactivity_timer;
int32_t ul_failure_timer;
uint32_t ue_reestablishment_reject_timer;
uint32_t ue_reestablishment_reject_timer_thres;
int32_t ul_scheduled;
int32_t ra_pdcch_order_sent;
int32_t ul_out_of_sync;
@@ -855,6 +860,7 @@ typedef struct {
uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
uint8_t dl_cqi[NFAPI_CC_MAX];
int32_t uplane_inactivity_timer;
} UE_sched_ctrl;
/*! \brief eNB template for the Random access information */
typedef struct {
@@ -982,6 +988,10 @@ typedef struct {
uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
/// Outgoing PCCH DCI allocation
uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu;
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
@@ -1102,6 +1112,8 @@ typedef struct eNB_MAC_INST_s {
time_stats_t schedule_mch;
/// processing time of eNB ULSCH reception
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
/// processing time of eNB PCH scheduler
time_stats_t schedule_pch;
} eNB_MAC_INST;
/*
+124 -51
View File
@@ -74,23 +74,25 @@ uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void
schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list;
nfapi_ul_config_request_body_t *ul_req;
int CC_id, UE_id;
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon;
struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated;
uint8_t TSFC;
uint16_t deltaTSFC; // bitmap
uint8_t srs_SubframeConfig;
eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list;
nfapi_ul_config_request_body_t *ul_req;
int CC_id, UE_id;
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon;
struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated;
uint8_t TSFC;
uint16_t deltaTSFC; // bitmap
uint8_t srs_SubframeConfig;
// table for TSFC (Period) and deltaSFC (offset)
const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD
const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
uint16_t srsPeriodicity, srsOffset;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
// check if SRS is enabled in this frame/subframe
@@ -98,26 +100,27 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig;
if (cc[CC_id].tdd_Config == NULL) { // FDD
deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
} else { // TDD
deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
}
// Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
uint16_t tmp = (subframeP % TSFC);
if ((1 << tmp) & deltaTSFC) {
// This is an SRS subframe, loop over UEs
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) continue;
if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE)
continue;
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
"physicalConfigDedicated is null for UE %d\n",
UE_id);
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
get_srs_pos(&cc[CC_id],
@@ -127,34 +130,31 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) {
// Program SRS
ul_req->srs_present = 1;
nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
memset((void *) ul_config_pdu, 0,
sizeof
(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);;
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
// ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;//
nfapi_ul_config_request_pdu_t * ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;//
// ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;//
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST;
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST;
ul_req->number_of_pdus++;
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // for (UE_id ...
} // if((1<<tmp) & deltaTSFC)
} // SRS config
} // for CC_id
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // for (UE_id ...
} // if((1<<tmp) & deltaTSFC)
} // SRS config
}
}
void
@@ -408,7 +408,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
// check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
// inform RRC of failure and clear timer
LOG_I(MAC,
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
@@ -419,6 +419,12 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
}
} // ul_failure_timer>0
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){
LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
}// time > 60s
}
void
@@ -521,10 +527,74 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
RC.mac[module_idP]->frame = frameP;
RC.mac[module_idP]->subframe = subframeP;
clear_nfapi_information(RC.mac[module_idP], CC_id, frameP,subframeP);
RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) +
subframeP] = -63;
if (i == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,
RC.eNB[module_idP][CC_id]->
pusch_stats_bsr[i][(frameP * 10) + subframeP]);
// increment this, it is cleared when we receive an sdu
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti,
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].
ul_inactivity_timer,
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
check_ul_failure(module_idP, CC_id, i, frameP, subframeP);
if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) {
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++;
if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >=
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) {
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0;
for (int ue_id_l = 0; ue_id_l < NUMBER_OF_UE_MAX; ue_id_l++) {
if (reestablish_rnti_map[ue_id_l][0] == rnti) {
// clear currentC-RNTI from map
reestablish_rnti_map[ue_id_l][0] = 0;
reestablish_rnti_map[ue_id_l][1] = 0;
break;
}
}
for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) {
LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii];
if((ulsch != NULL) && (ulsch->rnti == rnti)){
LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti);
clean_eNb_ulsch(ulsch);
}
}
for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) {
LTE_eNB_DLSCH_t *dlsch = RC.eNB[module_idP][CC_id]->dlsch[ii][0];
if((dlsch != NULL) && (dlsch->rnti == rnti)){
LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti);
clean_eNb_dlsch(dlsch);
}
}
for(int j = 0; j < 10; j++){
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body;
if(ul_req_tmp){
int pdu_number = ul_req_tmp->number_of_pdus;
for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
if(pdu_index < pdu_number -1){
memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
}
ul_req_tmp->number_of_pdus--;
}
}
}
}
rrc_mac_remove_ue(module_idP,rnti);
}
}
}
// refresh UE list based on UEs dropped by PHY in previous subframe
// refresh UE list based on UEs dropped by PHY in previous subframe
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue;
@@ -565,6 +635,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
module_idP);
pdcp_run(&ctxt);
rrc_rx_tx(&ctxt, 0, CC_id);
#if defined(Rel10) || defined(Rel14)
@@ -584,6 +655,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
schedule_mib(module_idP, frameP, subframeP);
// This schedules SI for legacy LTE and eMTC starting in subframeP
schedule_SI(module_idP, frameP, subframeP);
// This schedules Paging in subframeP
schedule_PCH(module_idP,frameP,subframeP);
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP
schedule_RA(module_idP, frameP, subframeP);
// copy previously scheduled UL resources (ULSCH + HARQ)
@@ -596,18 +669,18 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
schedule_SR(module_idP, frameP, subframeP);
// This schedules UCI_CSI in subframeP
schedule_CSI(module_idP, frameP, subframeP);
// This schedules DLSCH in subframeP
schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
// Allocate CCEs for good after scheduling is done
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
allocate_CCEs(module_idP, CC_id, subframeP, 0);
stop_meas(&RC.mac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,
VCD_FUNCTION_OUT);
+1 -1
View File
@@ -700,7 +700,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
// Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block
&cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case
&cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case
AssertFatal(rrc_sdu_length > 0,
"[MAC][eNB Scheduler] CCCH not allocated\n");
+4 -4
View File
@@ -197,7 +197,7 @@ schedule_SIB1_BR(module_id_t module_idP,
n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB];
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 1, module_idP, 0); // not used in this case
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case
AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19,
"schedulingInfoSIB1_BR_r13 %d > 18\n",
@@ -424,7 +424,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP,
if ((sf_mod_period < si_WindowLength_BR_r13)
&& ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 1, module_idP, 0); // not used in this case
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0); // not used in this case
AssertFatal(bcch_sdu_length > 0,
"RRC returned 0 bytes for SI-BR %d\n", i);
@@ -606,7 +606,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
dl_req = &dl_config_request->dl_config_request_body;
cc = &eNB->common_channels[CC_id];
mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 1, module_idP, 0); // not used in this case
mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case
LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length);
@@ -692,7 +692,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case
bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 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, frameP, CC_id, bcch_sdu_length);
+356 -3
View File
@@ -925,8 +925,8 @@ schedule_ue_spec(module_id_t module_idP,
if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit
LOG_D(MAC,
"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
module_idP, frameP, CC_id,
"[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
module_idP, frameP, subframeP, CC_id,
TBS - header_len_dcch);
sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used
(char *)
@@ -1073,6 +1073,7 @@ schedule_ue_spec(module_id_t module_idP,
header_len_dtch_last--;
}
num_sdus++;
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
} // no data for this LCID
else {
header_len_dtch -= 3;
@@ -1655,7 +1656,13 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
BCCH_pdu.payload[0]);
}
UE_id = find_UE_id(module_idP, rntiP);
if (rntiP==P_RNTI) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP);
return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
}
UE_id = find_UE_id(module_idP,rntiP);
if (UE_id != -1) {
LOG_D(MAC,
@@ -1770,3 +1777,349 @@ set_ue_dai(sub_frame_t subframeP,
break;
}
}
void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
{
/* DCI:format 1A/1C P-RNTI:0xFFFE */
/* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
uint16_t pcch_sdu_length;
int mcs = -1;
int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc;
uint8_t *vrb_map;
int n_rb_dl;
int first_rb = -1;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req;
#ifdef FORMAT1C
int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */
const int GAP_MAP [9][2] = {
{-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/
{4, 0}, /* N_RB_DL [11] */
{8, 0}, /* N_RB_DL [12-19] */
{12, 0}, /* N_RB_DL [20-26] */
{18, 0}, /* N_RB_DL [27-44] */
{27, 0}, /* N_RB_DL [45-49] */
{27, 9}, /* N_RB_DL [50-63] */
{32, 16}, /* N_RB_DL [64-79] */
{48, 16} /* N_RB_DL [80-110] */
};
uint8_t n_rb_step = 0;
uint8_t n_gap = 0;
uint8_t n_vrb_dl = 0;
uint8_t Lcrbs = 0;
uint16_t rb_bit = 168; /* RB bit number value is unsure */
#endif
start_meas(&eNB->schedule_pch);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id];
vrb_map = (void*)&cc->vrb_map;
n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (uint16_t i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_PF_PO[CC_id][i].enable_flag != TRUE) {
continue;
}
if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) {
pcch_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
frameP,
PCCH,1,
&cc->PCCH_pdu.payload[0],
i); // used for ue index
if (pcch_sdu_length == 0) {
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP);
continue;
}
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length);
#ifdef FORMAT1C
//NO SIB
if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
(subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
switch (n_rb_dl) {
#if 0
case 6:
n_gap = n_rb_dl/2; /* expect: 3 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */
first_rb = 0;
break;
case 15:
n_gap = GAP_MAP[2][0]; /* expect: 8 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */
first_rb = 6;
break;
#endif
case 25:
n_gap = GAP_MAP[3][0]; /* expect: 12 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */
first_rb = 10;
break;
case 50:
n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */
if (gap_index > 0) {
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */
} else {
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */
}
first_rb = 24;
break;
case 100:
n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */
if (gap_index > 0) {
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */
} else {
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */
}
first_rb = 48;
break;
}
} else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging
switch (n_rb_dl) {
#if 0
case 6:
n_gap = n_rb_dl/2; /* expect: 3 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */
first_rb = 0;
break;
case 15:
n_gap = GAP_MAP[2][0]; /* expect: 8 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */
first_rb = 10;
break;
#endif
case 25:
n_gap = GAP_MAP[3][0]; /* expect: 12 */
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */
first_rb = 14;
break;
case 50:
n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */
if (gap_index > 0) {
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */
} else {
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */
}
first_rb = 28;
break;
case 100:
n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */
if (gap_index > 0) {
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */
} else {
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */
}
first_rb = 52;
break;
}
}
/* Get MCS for length of PCH */
if (pcch_sdu_length <= TBStable1C[0]) {
mcs=0;
} else if (pcch_sdu_length <= TBStable1C[1]) {
mcs=1;
} else if (pcch_sdu_length <= TBStable1C[2]) {
mcs=2;
} else if (pcch_sdu_length <= TBStable1C[3]) {
mcs=3;
} else if (pcch_sdu_length <= TBStable1C[4]) {
mcs=4;
} else if (pcch_sdu_length <= TBStable1C[5]) {
mcs=5;
} else if (pcch_sdu_length <= TBStable1C[6]) {
mcs=6;
} else if (pcch_sdu_length <= TBStable1C[7]) {
mcs=7;
} else if (pcch_sdu_length <= TBStable1C[8]) {
mcs=8;
} else if (pcch_sdu_length <= TBStable1C[9]) {
mcs=9;
} else {
/* unexpected: pcch sdb size is over max value*/
LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n",
module_idP, frameP,CC_id, pcch_sdu_length);
return;
}
rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1;
/* calculate N_RB_STEP and Lcrbs */
if (n_rb_dl < 50) {
n_rb_step = 2;
Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2);
} else {
n_rb_step = 4;
Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4);
}
for(i = 0;i < Lcrbs ;i++){
vrb_map[first_rb+i] = 1;
}
#else
//NO SIB
if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
(subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
switch (n_rb_dl) {
case 25:
first_rb = 10;
break;
case 50:
first_rb = 24;
break;
case 100:
first_rb = 48;
break;
}
} else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging
switch (n_rb_dl) {
case 25:
first_rb = 14;
break;
case 50:
first_rb = 28;
break;
case 100:
first_rb = 52;
break;
}
}
vrb_map[first_rb] = 1;
vrb_map[first_rb+1] = 1;
vrb_map[first_rb+2] = 1;
vrb_map[first_rb+3] = 1;
/* Get MCS for length of PCH */
if (pcch_sdu_length <= get_TBS_DL(0,3)) {
mcs=0;
} else if (pcch_sdu_length <= get_TBS_DL(1,3)) {
mcs=1;
} else if (pcch_sdu_length <= get_TBS_DL(2,3)) {
mcs=2;
} else if (pcch_sdu_length <= get_TBS_DL(3,3)) {
mcs=3;
} else if (pcch_sdu_length <= get_TBS_DL(4,3)) {
mcs=4;
} else if (pcch_sdu_length <= get_TBS_DL(5,3)) {
mcs=5;
} else if (pcch_sdu_length <= get_TBS_DL(6,3)) {
mcs=6;
} else if (pcch_sdu_length <= get_TBS_DL(7,3)) {
mcs=7;
} else if (pcch_sdu_length <= get_TBS_DL(8,3)) {
mcs=8;
} else if (pcch_sdu_length <= get_TBS_DL(9,3)) {
mcs=9;
}
#endif
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
#ifdef FORMAT1C
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap;
#else
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
#endif
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
// Rel10 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3;
// Rel13 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF;
if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) {
LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP);
dl_req->number_dci++;
dl_req->number_pdu++;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE;
#ifdef FORMAT1C
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
#else
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
#endif
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
TX_req->pdu_length = pcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = pcch_sdu_length;
TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
} else {
LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP);
continue;
}
if (opt_enabled == 1) {
trace_pdu(1,
&eNB->common_channels[CC_id].PCCH_pdu.payload[0],
pcch_sdu_length,
0xffff,
PCCH,
P_RNTI,
eNB->frame,
eNB->subframe,
0,
0);
LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff, pcch_sdu_length);
}
eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1;
eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length;
eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length;
eNB->eNB_stats[CC_id].pcch_mcs=mcs;
//paging first_rb log
LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb);
pthread_mutex_lock(&ue_pf_po_mutex);
memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t));
pthread_mutex_unlock(&ue_pf_po_mutex);
}
}
}
/* this might be misleading when pcch is inactive */
stop_meas(&eNB->schedule_pch);
return;
}
+1 -2
View File
@@ -545,8 +545,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
module_idP, CC_id, frameP, subframeP, i, j);
mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], 1, // this is eNB
module_idP, // index
mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0],
i); // this is the mbsfn sync area index
if (mcch_sdu_length > 0) {
+61 -37
View File
@@ -1859,6 +1859,8 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
sizeof(UE_sched_ctrl));
memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0,
sizeof(eNB_UE_STATS));
UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
@@ -1888,49 +1890,71 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP)
//------------------------------------------------------------------------------
{
int i;
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
int UE_id = find_UE_id(mod_idP, rntiP);
int pCC_id;
int i;
int j;
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
int UE_id = find_UE_id(mod_idP,rntiP);
int pCC_id;
if (UE_id == -1) {
LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP);
LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
return 0;
}
pCC_id = UE_PCCID(mod_idP, UE_id);
LOG_I(MAC, "Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id,
pCC_id, rntiP);
dump_ue_list(UE_list, 0);
pCC_id = UE_PCCID(mod_idP,UE_id);
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
dump_ue_list(UE_list,0);
UE_list->active[UE_id] = FALSE;
UE_list->num_UEs--;
if (UE_list->head == UE_id)
UE_list->head = UE_list->next[UE_id];
else
UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id];
if (UE_list->head_ul == UE_id)
UE_list->head_ul = UE_list->next_ul[UE_id];
else
UE_list->next_ul[prev(UE_list, UE_id, 0)] =
UE_list->next_ul[UE_id];
if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id];
else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id];
if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id];
else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id];
// clear all remaining pending transmissions
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][UE_id].ul_SR = 0;
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE;
/* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][UE_id].ul_SR = 0;
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
*/
memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE));
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0;
for ( j = 0; j < NB_RB_MAX; j++ ) {
UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0;
}
UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0;
for ( j = 0; j < NB_RB_MAX; j++ ) {
UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0;
}
UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
// check if this has an RA process active
RA_t *ra;
for (i = 0; i < NB_RA_PROC_MAX; i++) {
@@ -1943,7 +1967,7 @@ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP)
//break;
}
}
return 0;
}
+5 -3
View File
@@ -614,7 +614,7 @@ rx_sdu(const module_id_t enb_mod_idP,
CCCH,
(uint8_t *) payload_ptr,
rx_lengths[i],
ENB_FLAG_YES, enb_mod_idP, 0);
0);
if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest
@@ -732,6 +732,8 @@ rx_sdu(const module_id_t enb_mod_idP,
num_pdu_rx[rx_lcids[i]] += 1;
UE_list->eNB_UE_stats[CC_idP][UE_id].
num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
//clear uplane_inactivity_timer
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
} else { /* rx_length[i] */
UE_list->eNB_UE_stats[CC_idP][UE_id].
num_errors_rx += 1;
@@ -1190,8 +1192,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round,
UE_id, rnti);
LOG_D(MAC,
"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
module_idP, frameP, subframeP, harq_pid, UE_id, rnti,
"[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti,
CC_id, aggregation, N_RB_UL);
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP *
+1 -5
View File
@@ -32,10 +32,6 @@
#ifndef __MAC_EXTERN_H__
#define __MAC_EXTERN_H__
#ifdef USER_MODE
//#include "stdio.h"
#endif //USER_MODE
#include "PHY/defs.h"
#include "defs.h"
@@ -101,4 +97,4 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#endif //DEF_H
#endif //DEF_H
-88
View File
@@ -47,76 +47,6 @@
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
void dl_phy_sync_success(module_id_t module_idP, 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)
int mme_enabled = 1;
#else
int mme_enabled = 0;
#endif
if (first_sync == 1 && !(mme_enabled == 1)) {
//layer2_init_UE(module_idP);
openair_rrc_ue_init(module_idP, eNB_index);
} else {
rrc_in_sync_ind(module_idP, frameP, 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_ue(int eMBMS_active, char *uecap_xer,
uint8_t cba_group_active, uint8_t HO_active)
{
int i;
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));
AssertFatal(UE_mac_inst != NULL,
"[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n",
NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST,
sizeof(UE_MAC_INST));
LOG_D(MAC, "[MAIN] ALLOCATE %zu 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] calling RRC\n");
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
HO_active);
LOG_I(MAC, "[MAIN][INIT] Init function finished\n");
return (0);
}
void mac_top_init_eNB(void)
@@ -248,10 +178,6 @@ int rlcmac_init_global_param(void)
void mac_top_cleanup(void)
{
#ifndef USER_MODE
pdcp_module_cleanup();
#endif
if (NB_UE_INST > 0) {
free(UE_mac_inst);
}
@@ -262,20 +188,6 @@ void mac_top_cleanup(void)
}
int
l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
uint8_t HO_active)
{
LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
// NB_NODE=2;
// NB_INST=2;
rlcmac_init_global_param();
LOG_I(MAC, "[MAIN] init UE MAC functions \n");
mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active);
return (1);
}
int l2_init_eNB(void)
{
+150
View File
@@ -0,0 +1,150 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file main.c
* \brief top init of Layer 2
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 1.0
* \email: navid.nikaein@eurecom.fr
* @ingroup _mac
*/
#include "defs.h"
#include "proto.h"
#include "extern.h"
#include "assertions.h"
#include "PHY_INTERFACE/extern.h"
#include "PHY/defs.h"
#include "SCHED/defs.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
#include "RRC/LITE/defs.h"
#include "UTIL/LOG/log.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "SCHED/defs.h"
#include "common/ran_context.h"
extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
void dl_phy_sync_success(module_id_t module_idP, 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)
int mme_enabled = 1;
#else
int mme_enabled = 0;
#endif
if (first_sync == 1 && !(mme_enabled == 1)) {
//layer2_init_UE(module_idP);
openair_rrc_ue_init(module_idP, eNB_index);
} else {
rrc_in_sync_ind(module_idP, frameP, 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_ue(int eMBMS_active, char *uecap_xer,
uint8_t cba_group_active, uint8_t HO_active)
{
int i;
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));
AssertFatal(UE_mac_inst != NULL,
"[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n",
NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST,
sizeof(UE_MAC_INST));
LOG_D(MAC, "[MAIN] ALLOCATE %zu 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] calling RRC\n");
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
HO_active);
LOG_I(MAC, "[MAIN][INIT] Init function finished\n");
return (0);
}
int rlcmac_init_global_param_ue(void)
{
LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n");
if (rlc_module_init() != 0) {
return (-1);
}
pdcp_layer_init();
LOG_I(MAC, "[MAIN] Init Global Param Done\n");
return 0;
}
int
l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
uint8_t HO_active)
{
LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
// NB_NODE=2;
// NB_INST=2;
rlcmac_init_global_param_ue();
LOG_I(MAC, "[MAIN] init UE MAC functions \n");
mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active);
return (1);
}
-6
View File
@@ -59,12 +59,6 @@
//#define ICIC 0
/*
#ifndef USER_MODE
#define msg debug_msg
#endif
*/
/* this function checks that get_eNB_UE_stats returns
* a non-NULL pointer for all the active CCs of an UE
*/
+8
View File
@@ -426,6 +426,14 @@ void set_ue_dai(sub_frame_t subframeP,
int UE_id,
uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list);
/** \brief First stage of PCH Scheduling. Gets a PCH SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
@param paging_ue_index
*/
void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP);
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,
+2 -2
View File
@@ -372,14 +372,14 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
if (UE_mac_inst[module_idP].RA_active == 0) {
LOG_I(MAC, "RA not active\n");
// check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP,
Size = mac_rrc_data_req_ue(module_idP,
CC_id,
frameP,
CCCH, 1,
&UE_mac_inst[module_idP].
CCCH_pdu.payload[sizeof
(SCH_SUBHEADER_SHORT)
+ 1], 0, eNB_indexP,
+ 1], eNB_indexP,
0);
Size16 = (uint16_t) Size;
-101
View File
@@ -182,104 +182,3 @@ fill_rar_br(eNB_MAC_INST * eNB,
}
#endif
//------------------------------------------------------------------------------
uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload
)
//------------------------------------------------------------------------------
{
uint16_t ret = 0; // return value
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
// get the last RAR payload for working with CMW500
uint8_t n_rarpy = 0; // number of RAR payloads
uint8_t n_rarh = 0; // number of MAC RAR subheaders
uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
while (1) {
n_rarh++;
if (rarh->T == 1) {
n_rarpy++;
LOG_D(MAC, "RAPID %d\n", rarh->RAPID);
}
if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
rarh->RAPID);
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
break;
}
if (abs((int) rarh->RAPID - (int) preamble_index) <
abs((int) best_rx_rapid - (int) preamble_index)) {
best_rx_rapid = rarh->RAPID;
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
}
if (rarh->E == 0) {
LOG_I(PHY,
"No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
best_rx_rapid);
break;
} else {
rarh++;
}
};
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
n_rarh, n_rarpy);
if (CC_id > 0) {
LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
return (0xffff);
}
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);
#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);
LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP,
rarh->RAPID);
// LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R);
LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
// LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag);
// LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc);
// LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs);
// LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC);
// LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay);
// LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req);
LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP,
(uint16_t) rar[5] + (rar[4] << 8));
#endif
if (opt_enabled) {
LOG_D(OPT,
"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
module_idP, CC_id, frameP, ra_rnti);
trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
}
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);
ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
} else {
UE_mac_inst[module_idP].crnti = 0;
ret = (0xffff);
}
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
return ret;
}
+143
View File
@@ -0,0 +1,143 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file rar_tools.c
* \brief random access tools
* \author Raymond Knopp and navid nikaein
* \date 2011 - 2014
* \version 1.0
* @ingroup _mac
*/
#include "defs.h"
#include "proto.h"
#include "extern.h"
#include "SIMULATION/TOOLS/defs.h"
#include "UTIL/LOG/log.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "UTIL/OPT/opt.h"
#include "common/ran_context.h"
#define DEBUG_RAR
//------------------------------------------------------------------------------
uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload
)
//------------------------------------------------------------------------------
{
uint16_t ret = 0; // return value
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
// get the last RAR payload for working with CMW500
uint8_t n_rarpy = 0; // number of RAR payloads
uint8_t n_rarh = 0; // number of MAC RAR subheaders
uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
while (1) {
n_rarh++;
if (rarh->T == 1) {
n_rarpy++;
LOG_D(MAC, "RAPID %d\n", rarh->RAPID);
}
if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
rarh->RAPID);
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
break;
}
if (abs((int) rarh->RAPID - (int) preamble_index) <
abs((int) best_rx_rapid - (int) preamble_index)) {
best_rx_rapid = rarh->RAPID;
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
}
if (rarh->E == 0) {
LOG_I(PHY,
"No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
best_rx_rapid);
break;
} else {
rarh++;
}
};
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
n_rarh, n_rarpy);
if (CC_id > 0) {
LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
return (0xffff);
}
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);
#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);
LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP,
rarh->RAPID);
// LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R);
LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
// LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag);
// LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc);
// LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs);
// LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC);
// LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay);
// LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req);
LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP,
(uint16_t) rar[5] + (rar[4] << 8));
#endif
if (opt_enabled) {
LOG_D(OPT,
"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
module_idP, CC_id, frameP, ra_rnti);
trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
}
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);
ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
} else {
UE_mac_inst[module_idP].crnti = 0;
ret = (0xffff);
}
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
return ret;
}
+10 -15
View File
@@ -71,11 +71,6 @@
extern uint8_t usim_test;
/*
#ifndef USER_MODE
#define msg debug_msg
#endif
*/
mapping BSR_names[] = {
{"NONE", 0},
{"SHORT BSR", 1},
@@ -520,13 +515,13 @@ ue_send_sdu(module_id_t module_idP,
LOG_T(MAC, "\n");
#endif
mac_rrc_data_ind(module_idP,
mac_rrc_data_ind_ue(module_idP,
CC_id,
frameP, subframeP,
UE_mac_inst[module_idP].crnti,
CCCH,
(uint8_t *) payload_ptr,
rx_lengths[i], ENB_FLAG_NO, eNB_index, 0);
rx_lengths[i], eNB_index, 0);
} else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
LOG_D(MAC,
@@ -589,9 +584,9 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP,
LOG_D(MAC, "[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n",
module_idP, frameP, BCCH, len);
mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe
mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe
SI_RNTI,
BCCH, (uint8_t *) pdu, len, ENB_FLAG_NO, eNB_index,
BCCH, (uint8_t *) pdu, len, eNB_index,
0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
@@ -627,9 +622,9 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP,
"[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n",
module_idP, frameP, PCCH, len);
mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe
mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe
P_RNTI,
PCCH, (uint8_t *) pdu, len, ENB_FLAG_NO, eNB_index,
PCCH, (uint8_t *) pdu, len, eNB_index,
0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT);
@@ -749,10 +744,10 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",
module_idP, frameP, i, sync_area, eNB_index,
rx_lengths[i]);
mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe
mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe
M_RNTI,
MCCH,
payload_ptr, rx_lengths[i], 0, eNB_index,
payload_ptr, rx_lengths[i], eNB_index,
sync_area);
} else if (rx_lcids[i] == MTCH) {
if (UE_mac_inst[module_idP].msi_status == 1) {
@@ -2235,10 +2230,10 @@ ue_scheduler(const module_id_t module_idP,
UE_mac_inst[module_idP].rxSubframe = rxSubframeP;
#ifdef CELLULAR
rrc_rx_tx(module_idP, txFrameP, 0, eNB_indexP);
rrc_rx_tx_ue(module_idP, txFrameP, 0, eNB_indexP);
#else
switch (rrc_rx_tx(&ctxt, eNB_indexP, CC_id)) {
switch (rrc_rx_tx_ue(&ctxt, eNB_indexP, CC_id)) {
case RRC_OK:
break;
-3
View File
@@ -32,9 +32,6 @@
#ifndef __MAC_VARS_H__
#define __MAC_VARS_H__
#ifdef USER_MODE
//#include "stdio.h"
#endif //USER_MODE
#include "PHY/defs.h"
#include "defs.h"
#include "COMMON/mac_rrc_primitives.h"
-4
View File
@@ -54,10 +54,6 @@ SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_reassembly.c
SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_receiver.c
SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_dar.c
ifeq ($(OPENAIR_EMU),1)
SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_very_simple_test.c
endif
SOURCES_L2 += $(RLC_DIR)/rlc_mac.c
SOURCES_L2 += $(RLC_DIR)/rlc.c
SOURCES_L2 += $(RLC_DIR)/rlc_rrc.c
+39 -73
View File
@@ -30,9 +30,6 @@
#define PDCP_C
//#define DEBUG_PDCP_FIFO_FLUSH_SDU
#ifndef USER_MODE
#include <rtai_fifos.h>
#endif
#include "assertions.h"
#include "hashtable.h"
#include "pdcp.h"
@@ -64,10 +61,10 @@
# include "gtpv1u.h"
#endif
#ifndef OAI_EMU
extern int otg_enabled;
#endif
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
//-----------------------------------------------------------------------------
/*
@@ -439,11 +436,6 @@ pdcp_data_ind(
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN);
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP);
#endif
#ifdef PDCP_MSG_PRINT
int i=0;
LOG_F(PDCP,"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP);
@@ -638,11 +630,11 @@ pdcp_data_ind(
PROTOCOL_PDCP_CTXT_FMT" DATA-IND len %u",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len);
rrc_data_ind(ctxt_pP,
rrc_data_ind(ctxt_pP,
rb_id,
sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len,
(uint8_t*)&sdu_buffer_pP->data[pdcp_header_len]);
free_mem_block(sdu_buffer_pP, __func__);
// free_mem_block(new_sdu, __func__);
if (ctxt_pP->enb_flag) {
@@ -691,49 +683,6 @@ pdcp_data_ind(
payload_offset=0;
}
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.otg_enabled == 1) {
//unsigned int dst_instance;
int ctime;
if ((pdcp_p->rlc_mode == RLC_MODE_AM)&&(MBMS_flagP==0) ) {
pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
}
#if defined(DEBUG_PDCP_PAYLOAD)
rlc_util_print_hex_octets(PDCP,
(unsigned char*)&sdu_buffer_pP->data[payload_offset],
sdu_buffer_sizeP - payload_offset);
#endif
ctime = oai_emulation.info.time_ms; // avg current simulation time in ms : we may get the exact time through OCG?
if (MBMS_flagP == 0){
LOG_D(PDCP,
PROTOCOL_PDCP_CTXT_FMT"Check received buffer : (dst %d)\n",
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
ctxt_pP->instance);
}
if (otg_rx_pkt(
ctxt_pP->instance,
ctime,
(const char*)(&sdu_buffer_pP->data[payload_offset]),
sdu_buffer_sizeP - payload_offset ) == 0 ) {
free_mem_block(sdu_buffer_pP, __func__);
if (ctxt_pP->enb_flag) {
stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_ind);
} else {
stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_ind);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
return TRUE;
}
}
#else
if (otg_enabled==1) {
LOG_D(OTG,"Discarding received packed\n");
free_mem_block(sdu_buffer_pP, __func__);
@@ -748,9 +697,6 @@ pdcp_data_ind(
return TRUE;
}
#endif
// XXX Decompression would be done at this point
/*
@@ -809,22 +755,15 @@ pdcp_data_ind(
// set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here
if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
#if defined(OAI_EMU)
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local;
#else
# if defined(ENABLE_USE_MME)
#if defined(ENABLE_USE_MME)
/* for the UE compiled in S1 mode, we need 1 here
* for the UE compiled in noS1 mode, we need 0
* TODO: be sure of this
*/
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1;
# endif
#endif
} else {
((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB);
#if defined(OAI_EMU)
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id - oai_emulation.info.first_enb_local;
#endif
}
#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU
static uint32_t pdcp_inst = 0;
@@ -948,6 +887,21 @@ pdcp_run (
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
case RRC_PCCH_DATA_REQ:
{
sdu_size_t sdu_buffer_sizeP;
sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id;
uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index;
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP;
if (sdu_buffer_sizeP > 0) {
memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP);
}
//paging pdcp log
LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP);
}
break;
default:
LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
break;
@@ -981,11 +935,6 @@ pdcp_run (
itti_send_msg_to_task(TASK_MAC_ENB, 3, msg_resp_p);
}
# endif
#endif
#if defined(USER_MODE) && defined(OAI_EMU)
pdcp_fifo_read_input_sdus_from_otg(ctxt_pP);
#endif
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
@@ -1037,6 +986,13 @@ pdcp_remove_UE(
// check and remove SRBs first
for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti){
pdcp_eNB_UE_instance_to_rnti[i] = NOT_A_RNTI;
break;
}
}
for (srb_id=0; srb_id<2; srb_id++) {
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
h_rc = hashtable_remove(pdcp_coll_p, key);
@@ -1344,7 +1300,7 @@ rrc_pdcp_config_asn1_req (
for (cnt=0; cnt<drb2release_list_pP->list.count; cnt++) {
pdrb_id_p = drb2release_list_pP->list.array[cnt];
drb_id = *pdrb_id_p;
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_NO);
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
if (h_rc != HASH_TABLE_OK) {
@@ -1472,7 +1428,17 @@ pdcp_config_req_asn1 (
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
pdcp_pP->is_ue = FALSE;
//pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti;
pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
// pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
if( srb_flagP == SRB_FLAG_NO ) {
for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI){
break;
}
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
}
pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
}
//pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
} else {
pdcp_pP->is_ue = TRUE;
+4 -155
View File
@@ -33,14 +33,11 @@
#define PDCP_DEBUG 1
//#define DEBUG_PDCP_FIFO_FLUSH_SDU
#ifndef OAI_EMU
extern int otg_enabled;
#endif
#include "pdcp.h"
#include "pdcp_primitives.h"
#ifdef USER_MODE
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
@@ -48,9 +45,6 @@ extern int otg_enabled;
#include <unistd.h>
#define rtf_put write
#define rtf_get read
#else
#include <rtai_fifos.h>
#endif //USER_MODE
#include "../MAC/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
@@ -168,11 +162,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP)
threadname, ctxt_pP->frame, ctxt_pP->subframe,
((pdcp_data_ind_header_t*) sdu_p->data)->inst,
((pdcp_data_ind_header_t *) sdu_p->data)->data_size);
#else
#if ! defined(OAI_EMU)
/* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
#endif
#endif
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
@@ -553,29 +542,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
#endif
#ifdef OAI_EMU
// overwrite function input parameters, because only one netlink socket for all instances
if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) {
ctxt.frame = ctxt_cpy.frame;
ctxt.enb_flag = ENB_FLAG_YES;
ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;
ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local];
rab_id = pdcp_read_header_g.rb_id % maxDRB;
} else {
ctxt.frame = ctxt_cpy.frame;
ctxt.enb_flag = ENB_FLAG_NO;
ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
rab_id = pdcp_read_header_g.rb_id % maxDRB;
}
CHECK_CTXT_ARGS(&ctxt);
AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB);
/*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \
pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/
#else // OAI_EMU
/* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
// pdcp_read_header_g.inst = 0;
//#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
@@ -589,16 +555,13 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
if (ctxt_cpy.enb_flag) {
ctxt.module_id = 0;
rab_id = pdcp_read_header_g.rb_id % maxDRB;
ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index];
ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB];
} else {
ctxt.module_id = 0;
rab_id = pdcp_read_header_g.rb_id % maxDRB;
ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
}
#endif
if (ctxt.enb_flag) {
if (rab_id != 0) {
rab_id = rab_id % maxDRB;
@@ -810,121 +773,8 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP)
module_id_t dst_id; // dst for otg
rb_id_t rb_id;
unsigned int pkt_size=0;
#if defined(USER_MODE) && defined(OAI_EMU)
module_id_t src_id;
static unsigned int pkt_cnt_enb=0, pkt_cnt_ue=0;
Packet_otg_elt_t *otg_pkt_info=NULL;
int result;
uint8_t pdcp_mode, is_ue=0;
#endif
protocol_ctxt_t ctxt;
// we need to add conditions to avoid transmitting data when the UE is not RRC connected.
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.otg_enabled ==1 ) {
// module_id is source id
while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[ctxt_pP->instance]))) != NULL) {
LOG_I(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n",
ctxt_pP->module_id,
ctxt_pP->frame,
otg_pkt_info,
ctxt_pP->instance,
pkt_list_get_head(&(otg_pdcp_buffer[ctxt_pP->instance])),
otg_pdcp_buffer[ctxt_pP->instance].nb_elements);
//otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]));
dst_id = (otg_pkt_info->otg_pkt).dst_id; // type is module_id_t
src_id = (otg_pkt_info->otg_pkt).module_id; // type is module_id_t
rb_id = (otg_pkt_info->otg_pkt).rb_id;
is_ue = (otg_pkt_info->otg_pkt).is_ue;
pdcp_mode = (otg_pkt_info->otg_pkt).mode;
// LOG_I(PDCP,"pdcp_fifo, pdcp mode is= %d\n",pdcp_mode);
// generate traffic if the ue is rrc reconfigured state
// if (mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_enb
otg_pkt = (unsigned char*) (otg_pkt_info->otg_pkt).sdu_buffer;
pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size;
if (otg_pkt != NULL) {
if (is_ue == 0 ) {
PROTOCOL_CTXT_SET_BY_MODULE_ID(
&ctxt,
src_id,
ENB_FLAG_YES,
oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id],
ctxt_pP->frame,
ctxt_pP->subframe,
src_id);
LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d/%x) pkt size %d for pdcp mode %d\n",
ctxt.module_id,
ctxt.frame,
pkt_cnt_enb++,
src_id,
rb_id,
src_id,
dst_id,
oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id],
pkt_size,
pdcp_mode);
result = pdcp_data_req(&ctxt,
SRB_FLAG_NO,
rb_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
pkt_size,
otg_pkt,
pdcp_mode);
if (result != TRUE) {
LOG_W(OTG,"PDCP data request failed!\n");
}
} else {
//rb_id= eNB_index * MAX_NUM_RB + DTCH;
LOG_D(OTG,"[UE %d] Frame %d: sending packet %d from module %d on rab id %d (src %d/%x, dst %d) pkt size %d\n",
ctxt_pP->module_id,
ctxt_pP->frame,
pkt_cnt_ue++,
ctxt_pP->module_id,
rb_id,
src_id,
pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id], // [src_id]
dst_id,
pkt_size);
PROTOCOL_CTXT_SET_BY_MODULE_ID(
&ctxt,
ctxt_pP->module_id, //src_id,
ENB_FLAG_NO,
pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id],// [src_id]
ctxt_pP->frame,
ctxt_pP->subframe,
dst_id);
result = pdcp_data_req( &ctxt,
SRB_FLAG_NO,
rb_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
pkt_size,
otg_pkt,
PDCP_TRANSMISSION_MODE_DATA);
if (result != TRUE) {
LOG_W(OTG,"PDCP data request failed!\n");
}
}
free(otg_pkt);
otg_pkt = NULL;
}
// } //else LOG_D(OTG,"ctxt_pP->frame %d enb %d-> ue %d link not yet established state %d \n", ctxt_pP->frame, eNB_index,dst_id - NB_eNB_INST, mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id - NB_eNB_INST));
}
}
#else
if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic
unsigned int ctime=0;
ctime = ctxt_pP->frame * 100;
@@ -942,9 +792,9 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP)
for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id];
/*
if (ctxt.rnti != NOT_A_RNTI) {
if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 /*RRC_SI_RECEIVED*/) {
if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 ) {
unsigned int temp = 0;
otg_pkt=packet_gen(
ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id),
@@ -971,8 +821,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP)
}
}
}
*/
}
}
#endif
}
@@ -101,13 +101,8 @@ pdcp_netlink_init(
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;
nb_inst_ue = oai_emulation.info.nb_ue_local;
#else
nb_inst_enb = 1;
nb_inst_ue = 1;
#endif
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
nb_inst_enb = 0;
@@ -259,24 +254,7 @@ void *pdcp_netlink_thread_fct(void *arg)
}
} else {
pdcp_thread_read_state = 0;
#ifdef OAI_EMU
// 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);
@@ -110,9 +110,7 @@ int init_pdcp_thread(void)
p.sched_priority = OPENAIR_THREAD_PRIORITY;
pthread_attr_setschedparam (&pdcp_thread_attr, &p);
#ifndef RTAI_ISNT_POSIX
pthread_attr_setschedpolicy (&pdcp_thread_attr, SCHED_FIFO);
#endif
pthread_mutex_init(&pdcp_mutex,NULL);
pthread_cond_init(&pdcp_cond,NULL);
-4
View File
@@ -73,10 +73,6 @@
# include "RLC-Config.h"
//# include "rlc_am_test.h"
#ifdef USER_MODE
//# include "rlc_am_very_simple_test.h"
#endif
#define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]"
#define PROTOCOL_RLC_AM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\
@@ -21,9 +21,7 @@
#define RLC_AM_MODULE 1
#define RLC_AM_INIT_C 1
#ifdef USER_MODE
#include <string.h>
#endif
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
@@ -268,11 +268,9 @@ rlc_am_reassemble_pdu(
//}
break;
#if USER_MODE
default:
assert(0 != 0);
#endif
}
} else {
switch (pdu_info->fi) {
@@ -382,19 +380,13 @@ rlc_am_reassemble_pdu(
if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug
// data is already ok, done by last loop above
rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size);
} else {
#if USER_MODE
//assert (5!=5);
#endif
}
//rlc_pP->reassembly_missing_sn_detected = 0;
break;
#if USER_MODE
default:
assert(1 != 1);
#endif
}
}
@@ -22,9 +22,7 @@
#define RLC_AM_MODULE 1
#define RLC_AM_SEGMENT_C 1
//-----------------------------------------------------------------------------
#if USER_MODE
#include <assert.h>
#endif
//-----------------------------------------------------------------------------
#include "platform_types.h"
//-----------------------------------------------------------------------------
@@ -468,9 +466,7 @@ void rlc_am_segment_10 (
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
sdu_mngt_p->sdu_remaining_size,
pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
#if USER_MODE
assert(1!=1);
#endif
memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size;
pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
@@ -36,9 +36,7 @@
# include "list.h"
# include "mem_block.h"
# include "rlc_am_constants.h"
//#ifdef USER_MODE
# include "mac_rlc_primitives.h"
//#endif //USER_MODE
# include "mac_primitives.h"
# include "rlc_primitives.h"
/**
@@ -22,9 +22,7 @@
#define RLC_AM_MODULE 1
#define RLC_AM_WINDOWS_C 1
//-----------------------------------------------------------------------------
#if USER_MODE
#include <assert.h>
#endif
//-----------------------------------------------------------------------------
#include "platform_types.h"
//-----------------------------------------------------------------------------
@@ -125,6 +125,7 @@ rlc_tm_cleanup (
// RX SIDE
if ((rlcP->output_sdu_in_construction)) {
free_mem_block (rlcP->output_sdu_in_construction, __func__);
rlcP->output_sdu_in_construction = NULL;
}
memset(rlcP, 0, sizeof(rlc_tm_entity_t));
-4
View File
@@ -682,10 +682,6 @@ rlc_um_data_req (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, mem_block_t
{
rlc_um_entity_t *rlc_p = (rlc_um_entity_t *) rlc_pP;
#if ! USER_MODE
unsigned long int rlc_um_time_us;
int min, sec, usec;
#endif
#if TRACE_RLC_UM_PDU
#if ENABLE_ITTI
MessageDef *msg_p;
-3
View File
@@ -64,9 +64,6 @@
# include "rlc_um_receiver.h"
# include "rlc_um_segment.h"
# include "rlc_um_test.h"
#ifdef USER_MODE
//# include "rlc_um_very_simple_test.h"
#endif
#define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] %s()"
#define PROTOCOL_RLC_UM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\
@@ -343,6 +343,7 @@ rlc_um_cleanup (
if ((rlc_pP->output_sdu_in_construction)) {
free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
rlc_pP->output_sdu_in_construction = NULL;
}
if (rlc_pP->dar_buffer) {
@@ -23,9 +23,7 @@
#define RLC_UM_REASSEMBLY_C 1
#include "platform_types.h"
//-----------------------------------------------------------------------------
#if USER_MODE
#include <string.h>
#endif
#if ENABLE_ITTI
# include "platform_types.h"
# include "intertask_interface.h"
@@ -25,9 +25,7 @@
#include "platform_types.h"
#include "platform_constants.h"
//-----------------------------------------------------------------------------
#if USER_MODE
#include <assert.h>
#endif
#include "assertions.h"
#include "msc.h"
#include "list.h"
@@ -367,10 +365,8 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP
sdu_mngt_p->sdu_remaining_size,
pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
#endif
#if USER_MODE
#if !EXMIMO
assert(1!=1);
#endif
#endif
memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
// reduce the size of the PDU
@@ -754,9 +750,7 @@ rlc_um_segment_5 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP)
sdu_mngt_p->sdu_remaining_size,
pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
#endif
#if USER_MODE
assert(1!=1);
#endif
memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
// reduce the size of the PDU
continue_fill_pdu_with_sdu = 0;
@@ -36,9 +36,7 @@
# include "rlc_um_constants.h"
# include "mac_primitives.h"
# include "rlc_primitives.h"
//#ifdef USER_MODE
# include "mac_rlc_primitives.h"
//#endif //USER_MODE
//-----------------------
/**
* @addtogroup _rlc_um_impl_
-10
View File
@@ -135,11 +135,6 @@ rlc_op_status_t rlc_stat_req (
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
@@ -346,11 +341,6 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP,
#else
AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP);
#endif
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
#if T_TRACER
if (ctxt_pP->enb_flag)
-4
View File
@@ -662,10 +662,6 @@ public_rlc(rlc_op_status_t rlc_stat_req (
public_rlc(int rlc_module_init(void);)
/** @} */
#ifndef USER_MODE
#define assert(x) ((x)?msg("rlc assertion fails\n"):0)
#endif
#define RLC_FG_COLOR_BLACK "\e[0;30m"
#define RLC_FG_COLOR_RED "\e[0;31m"
-44
View File
@@ -157,13 +157,6 @@ tbs_size_t mac_rlc_data_req(
AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n", channel_idP, NB_RB_MAX);
}
#ifdef OAI_EMU
CHECK_CTXT_ARGS(&ctxt);
//printf("MBMS_flagP %d, MBMS_FLAG_NO %d \n",MBMS_flagP, MBMS_FLAG_NO);
// AssertFatal (MBMS_flagP == MBMS_FLAG_NO ," MBMS FLAG SHOULD NOT BE SET IN mac_rlc_data_req in UE\n");
#endif
if (MBMS_flagP) {
if (enb_flagP) {
mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP];
@@ -256,18 +249,6 @@ void mac_rlc_data_ind (
}
#endif // DEBUG_MAC_INTERFACE
#ifdef OAI_EMU
if (MBMS_flagP)
AssertFatal (channel_idP < RLC_MAX_MBMS_LC, "channel id is too high (%u/%d)!\n",
channel_idP, RLC_MAX_MBMS_LC);
else
AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n",
channel_idP, NB_RB_MAX);
CHECK_CTXT_ARGS(&ctxt);
#endif
#if T_TRACER
if (enb_flagP)
@@ -347,31 +328,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
memset (&mac_rlc_status_resp, 0, sizeof(mac_rlc_status_resp_t));
memset (&tx_status , 0, sizeof(struct mac_status_ind));
#ifdef OAI_EMU
if (MBMS_flagP)
AssertFatal (channel_idP < RLC_MAX_MBMS_LC,
"%s channel id is too high (%u/%d) enb module id %u ue %u!\n",
(enb_flagP) ? "eNB" : "UE",
channel_idP,
RLC_MAX_MBMS_LC,
module_idP,
rntiP);
else
AssertFatal (channel_idP < NB_RB_MAX,
"%s channel id is too high (%u/%d) enb module id %u ue %u!\n",
(enb_flagP) ? "eNB" : "UE",
channel_idP,
NB_RB_MAX,
module_idP,
rntiP);
CHECK_CTXT_ARGS(&ctxt);
#endif
if (MBMS_flagP) {
if (enb_flagP) {
mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP];
+2 -4
View File
@@ -31,10 +31,8 @@
#ifndef __RLC_PRIMITIVES_H__
# define __RLC_PRIMITIVES_H__
# ifdef USER_MODE
# include <stdio.h>
# include <stdlib.h>
# endif
# include <stdio.h>
# include <stdlib.h>
# include "platform_types.h"
# include "platform_constants.h"
# include "mem_block.h"
-24
View File
@@ -33,9 +33,6 @@
#include "rlc_um.h"
#include "rlc_tm.h"
#include "UTIL/LOG/log.h"
#ifdef OAI_EMU
#include "UTIL/OCG/OCG_vars.h"
#endif
#include "RLC-Config.h"
#include "DRB-ToAddMod.h"
#include "DRB-ToAddModList.h"
@@ -88,12 +85,6 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 \n",
PROTOCOL_CTXT_ARGS(ctxt_pP));
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
if (srb2add_listP != NULL) {
for (cnt=0; cnt<srb2add_listP->list.count; cnt++) {
rb_id = srb2add_listP->list.array[cnt]->srb_Identity;
@@ -489,10 +480,6 @@ rlc_op_status_t rrc_rlc_remove_rlc (
rlc_union_t *rlc_union_p = NULL;
#if defined(Rel10) || defined(Rel14)
rlc_mbms_id_t *mbms_id_p = NULL;
#endif
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
/* for no gcc warnings */
@@ -597,12 +584,6 @@ rlc_union_t* rrc_rlc_add_rlc (
logical_chan_id_t lcid = 0;
#endif
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
if (MBMS_flagP == FALSE) {
AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC);
@@ -706,11 +687,6 @@ rlc_op_status_t rrc_rlc_config_req (
PROTOCOL_CTXT_ARGS(ctxt_pP),
rb_idP);
#ifdef OAI_EMU
CHECK_CTXT_ARGS(ctxt_pP)
#endif
AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
switch (actionP) {
+8 -52
View File
@@ -29,21 +29,7 @@
# @ingroup _openair2
*/
#ifdef USER_MODE
# include <inttypes.h>
#else
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
# ifndef PRIu64
# if __WORDSIZE == 64
# define PRIu64 "lu"
# else
# define PRIu64 "llu"
# endif
# endif
#endif
#include <inttypes.h>
#include "LAYER2/RLC/rlc.h"
#include "LAYER2/MAC/defs.h"
@@ -131,6 +117,12 @@ int dump_eNB_l2_stats(char *buffer, int length)
eNB->eNB_stats[CC_id].bcch_buffer,
eNB->eNB_stats[CC_id].total_bcch_buffer,
eNB->eNB_stats[CC_id].bcch_mcs);
len += sprintf(&buffer[len],"PCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n",
eNB->eNB_stats[CC_id].total_num_pcch_pdu,
eNB->eNB_stats[CC_id].pcch_buffer,
eNB->eNB_stats[CC_id].total_pcch_buffer,
eNB->eNB_stats[CC_id].pcch_mcs);
eNB->eNB_stats[CC_id].dlsch_bitrate=((eNB->eNB_stats[CC_id].dlsch_bytes_tx*8)/((eNB->frame + 1)*10));
eNB->eNB_stats[CC_id].total_dlsch_pdus_tx+=eNB->eNB_stats[CC_id].dlsch_pdus_tx;
@@ -236,7 +228,7 @@ int dump_eNB_l2_stats(char *buffer, int length)
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,
eNB_id,
ENB_FLAG_YES,
UE_list->eNB_UE_stats[UE_PCCID(eNB_id,UE_id)][UE_id].crnti,
UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti,
eNB->frame,
eNB->subframe,
eNB_id);
@@ -404,11 +396,7 @@ int dump_eNB_l2_stats(char *buffer, int length)
}
#ifdef PROC
#ifndef USER_MODE
static int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
#else
int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
#endif
{
int len = 0,fg,Overhead, Sign;
@@ -691,36 +679,4 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
return len;
}
#ifndef USER_MODE
static struct proc_dir_entry *proc_openair2_root;
/*
* Initialize the module and add the /proc file.
*/
int add_openair2_stats()
{
struct proc_dir_entry *pde;
proc_openair2_root = proc_mkdir("openair2",0);
// pde = proc_create_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root);
pde = proc_create_data("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, NULL,openair2_stats_read);
if (!pde) {
printk("[OPENAIR][ERROR] can't create proc entry !\n");
}
return 0;
}
/*
* Unregister the file when the module is closed.
*/
void remove_openair_stats()
{
if (proc_openair2_root) {
printk("[OPENAIR][CLEANUP] Removing openair proc entry\n");
remove_proc_entry("lchan_stats", proc_openair2_root);
}
}
#endif
#endif
-81
View File
@@ -1,81 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*________________________rrc_register.c________________________
Authors : Hicham Anouar, Raymond Knopp
Company : EURECOM
Emails : anouar@eurecom.fr, knopp@eurecom.fr
________________________________________________________________*/
#ifndef USER_MODE
#define __NO_VERSION__
#else
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#endif
#include "COMMON/openair_types.h"
#include "MAC/extern.h"
#include <linux/module.h>
#ifndef USER_MODE
//-----------------------------------------------------------------------------------------------------------//
MAC_RLC_XFACE* mac_rrc_register(RRC_XFACE* RRC_xface)
{
//-----------------------------------------------------------------------------------------------------------//
if(Is_rrc_registered) {
msg("[OPENAIR][MAC][RRC_REGISTER] RRC interface already registered, aborting ...\n");
return NULL;
} else {
msg("[OPENAIR][MAC][RRC_REGISTER] Registering RRC Interface, Mac_rlc_xface=%p\n",Mac_rlc_xface);
Rrc_xface=RRC_xface;
Is_rrc_registered=1;
return Mac_rlc_xface;
}
}
//-----------------------------------------------------------------------------------------------------------//
int mac_rrc_unregister(RRC_XFACE *RRC_xface)
{
//-----------------------------------------------------------------------------------------------------------//
if (Rrc_xface == RRC_xface) {
msg("[OPENAIR][MAC XFACE][RRC_UNREGISTER] Unregistering RRC interface\n");
Rrc_xface=NULL;
Is_rrc_registered=0;
return(0);
} else {
msg("[OPENAIR][MAC XFACE][RRC_UNREGISTER] Not the right interface descriptor pointer!!!, aborting ...\n");
return (-1);
}
}
EXPORT_SYMBOL(mac_rrc_register);
EXPORT_SYMBOL(mac_rrc_unregister);
#endif //USER_MODE
-254
View File
@@ -1,254 +0,0 @@
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
####################################################
# USER SPACE CODE GENERATION
####################################################
#---------------------------------------------------
#
#---------------------------------------------------
#LM_LICENSE_FILE=
#export LM_LICENSE_FILE
include $(OPENAIR_DIR)/common/utils/Makefile.inc
KERNEL_NAME:=$(shell uname -r)
NUM_CORES=$(shell getconf _NPROCESSORS_CONF)
export SET_UM=$(shell if grep --silent User\ Mode\ Linux /proc/cpuinfo ; then echo "ARCH=um" ; else echo ""; fi)
#SUBDIRS_openair_USERRF = $(MAIN_RT_DIR) $(CONFIG_DIR)
#openair_USERRFDIR = openair_RFOBJS
#openair_USERRFLIBS = $(addsuffix /${openair_USERRFDIR}/Lib.a, ${SUBDIRS_openair_USERRF})
#openair_USERRFOBJS = $(addsuffix /${openair_USERRFDIR}/*.o, ${SUBDIRS_openair_USERRF})
#openair_USERRFDEPS = $(addsuffix /${openair_USERRFDIR}/*.d, ${SUBDIRS_openair_USERRF})
mac_sim_no_netlink:
( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim MASTER=1)
mac_sim:
( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim MASTER=1 NETLINK=1 NO_RRM=1)
mac_sim_rrm:
( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_rrm MASTER=1 NETLINK=1)
mac_sim_mt_cellular:
( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_mt CELLULAR=1 NO_RRM=1)
mac_sim_rg_cellular:
( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_rg MASTER=1 CELLULAR=1 NO_RRM=1)
openair_layer2_emul.ko:
(cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` NO_RRM=1 PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 PHYEMUL=1 && mv openair_l2.ko openair_layer2.ko)
openair_layer2_emul_rrm.ko:
(cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 PHYEMUL=1 && mv openair_l2.ko openair_layer2.ko)
openair_layer2.ko:
(cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` NO_RRM=1 PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2.ko)
openair_layer2_rrm.ko:
(cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2.ko)
openair_layer2_2615.ko:
(cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2_2615.ko)
openair_rrc.ko:
(cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 NO_RRM=1 && mv openair_rrc.ko openair_RRC.ko)
openair_rrc_rrm.ko:
(cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 && mv openair_rrc.ko openair_RRC.ko)
openair_rrc_2615.ko:
(cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 && mv openair_rrc.ko openair_RRC_2615.ko)
openair_rrc_emul.ko:
(cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 PHYEMUL=1 NO_RRM=1)
openair_rrc_emul_rrm.ko:
(cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 PHYEMUL=1)
openair_emul.ko:
(cd SIMULATION/PHY_EMULATION/DEVICE_DRIVER/ && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 NO_RRM=1)
openair_emul_rrm.ko:
(cd SIMULATION/PHY_EMULATION/DEVICE_DRIVER/ && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1)
create_device:
rm -f /dev/openair0
mknod /dev/openair0 c 127 0
chmod a+rw /dev/openair0
install_emul:
make devs
make fifos
(insmod SIMULATION/PHY_EMULATION/DEVICE_DRIVER/openair_emul.ko)
(insmod LAYER2/openair_layer2.ko)
(insmod RRC/MESH/openair_rrc.ko)
(insmod NETWORK_DRIVER/MESH/nasmesh.ko)
remove_emul:
rmmod nasmesh
sleep 1
rmmod openair_rrc
sleep 1
rmmod openair_l2
sleep 1
rmmod openair_emul
clean_nasmesh:
(cd NETWORK_DRIVER/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` clean)
nasmesh_address_fix.ko:
(cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) V=1 ADDRESS_FIX=1 -C $(KERNEL_DIR)/build M=`pwd`)
nasmesh.ko:
(cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) V=1 -C $(KERNEL_DIR)/build M=`pwd`)
# automatically detect the linux header files for driver compilation
nasmesh_netlink.ko:
(cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
naslite_netlink_ether.ko:
(cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
oai_nw_ether.ko:
(cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
oai_nw_drv.ko:
(cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
nasmesh_netlink_address_fix.ko:
(cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 ADDRESS_FIX=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
nasmesh_netlink_loopback.ko:
(cd NETWORK_DRIVER/MESH && $(MAKE) $(SET_UM) PDCP_USE_NETLINK=1 LOOPBACK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
# drivers cellular version
nascellmt_netlink.ko:
(cd NAS/DRIVER/CELLULAR/NASMT && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
nascellmt_clean.ko:
(cd NAS/DRIVER/CELLULAR/NASMT && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` clean)
nascellrg_netlink.ko:
(cd NAS/DRIVER/CELLULAR/NASRG && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
nascellrg_clean.ko:
(cd NAS/DRIVER/CELLULAR/NASRG && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` clean)
# Driver for UE using LTE core network (MME, S+P-GW)
ue_ip.ko:
(cd NETWORK_DRIVER/UE_IP && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules)
rt_emul:
(cd SIMULATION/USER_TOOLS/RT_EMUL_LAUNCHER && $(MAKE))
bypass_phy:
(cd SIMULATION/PHY_EMULATION/TRANSPORT/KERNEL_INTERFACE && $(MAKE))
rb_tool:
(cd NETWORK_DRIVER/MESH/RB_TOOL && $(MAKE))
fifos:
@for i in `seq 0 64`;\
do \
have_rtfX=`ls /dev/ |grep -c rtf$$i`;\
if [ "$$have_rtfX" -eq 0 ] ;then \
mknod -m 666 /dev/rtf$$i c 150 $$i; \
fi;\
done
# cp arch/openair_CardBus_MIMO1/device_driver/openair_rf.ko $(KERNEL_DIR)/openair/
# depmod -aq
devs:
if ! test -a /dev/openair0;\
then \
mknod /dev/openair0 c 127 0;\
chmod a+rw /dev/openair0;\
fi;
load_sounder_ue: install_cbmimo1_ublaze
insmod mac/chansounder/openair_chansounder_ue.ko
load_sounder_nodeb: install_platon
(cd openair_rf && ./openair_rf_platon 1917600 0 ../arch/platon/rbt_files/DAQ_B.rbt 30p 15p 10p 25p && ./openair_rf_platon 1917600 0 ../arch/platon/rbt_files/daq_platon_11_2005.rbt 30p 15p 10p 25p)
stop_sounder:
rmmod openair_chansounder
rmmod openair_rf
stop_sounder_nodeb:
(cd openair_rf && ./openair_rf_platon 1907600 4)
rmmod openair_chansounder
rmmod openair_rf
emul_rt:
(cd SIMULATION/USER_TOOLS/RT_EMUL_LAUNCHER && $(MAKE))
clean:
(cd NETWORK_DRIVER/MESH && $(MAKE) clean)
(cd NETWORK_DRIVER/LITE && $(MAKE) clean)
rm -rf NETWORK_DRIVER/MESH/RB_TOOL/rb_tool
rm -rf NETWORK_DRIVER/LITE/RB_TOOL/rb_tool
cleanall:
find -name *.o -delete -print
find -name *.ko -delete -print
find -name *~ -delete -print
find -name *.bak -delete -print
rm -rf NETWORK_DRIVER/MESH/RB_TOOL/rb_tool
rm -rf NETWORK_DRIVER/LITE/RB_TOOL/rb_tool
cleansvn:
rm -rf `find -name *.svn* -print` ; \
find -name *.svn* -delete -print
tgz:
mkdir /tmp/openair2_tmp; \
$(MAKE) cleanall; \
cp -r . /tmp/openair2_tmp; \
(cd /tmp/openair2_tmp && $(MAKE) cleansvn && cd .. && tar czfv openair2.tgz openair2_tmp) ; \
cp /tmp/openair2.tgz . ;\
rm -rf /tmp/openair2_tmp
print:
@echo $(IS_KERNEL_OPENAIRINTERFACE)
@echo $(KERNEL_DIR)
@echo $(IS_LINUX)
@@ -1,48 +0,0 @@
# Lines starting with the pound sign are comments.
#
# These things are options that you might need
# to tweak.
# You can modify the below as well, but probably
# won't need to.
#CC = egcs
#UPDIR := $(shell /bin/pwd)
#GRAAL_DIR =$(UPDIR)/..
#RRC_DIR =$(UPDIR)/../../../AS/L3/RRC
CELL_UPDIR := $(shell /bin/pwd)
NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASMT
RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR
EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_MT
CFLAGS = -Wall -g -I$(NAS_DIR) -I$(RRC_DIR)
COMPILE = $(CC) $(CFLAGS) -c
OBJS = nascell_ioctl.o
EXECUTABLE = gioctl
# "all" is the default target. Simply make it point to myprogram.
all: $(EXECUTABLE)
# Define the components of the program, and how to link them together.
# These components are defined as dependencies; that is, they must be
# made up-to-date before the code is linked.
$(EXECUTABLE): $(OBJS)
$(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJS)
# Add any special rules here.
# Specify that all .o files depend on .c files, and indicate how
# the .c files are converted (compiled) to the .o files.
%.o: %.c
$(COMPILE) -o $@ $<
clean:
-rm $(OBJS) $(EXECUTABLE)
@@ -1,859 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nascell_ioctl.h"
#include "rrc_nas_primitives.h"
//#include "rrc_qos.h"
//#include "graal_local.h"
#include "nasmt_constant.h"
#include "nasmt_iocontrol.h"
#define USHRT_MAX 255
//---------------------------------------------------------------------------
void print_error(int status)
{
//---------------------------------------------------------------------------
switch(status) {
case -NAS_ERROR_NOMEMORY:
printf(" The memory is low\n");
break;
case -NAS_ERROR_NORB:
printf(" The radio bearer is not identified\n");
break;
case -NAS_ERROR_NOTMT:
printf(" The entity must be a mobile\n");
break;
case -NAS_ERROR_NOTRG:
printf(" The entity must be an access router\n");
break;
case -NAS_ERROR_NOTIDLE:
printf(" The selected connection or radio bearer must be IDLE\n");
break;
case -NAS_ERROR_NOTCONNECTED:
printf(" The selected connection or radio bearer must be CONNECTED\n");
break;
case -NAS_ERROR_NOTCORRECTLCR:
printf(" The LCR value is not correct\n");
break;
case -NAS_ERROR_NOTCORRECTDIR:
printf(" The DIR value is not correct\n");
break;
case -NAS_ERROR_NOTCORRECTDSCP:
printf(" The DSCP value is not correct\n");
break;
case -NAS_ERROR_NOTCORRECTVERSION:
printf(" The version value is not correct\n");
break;
case -NAS_ERROR_NOTCORRECTRABI:
printf(" The rab_id value is not correct\n");
break;
case -NAS_ERROR_ALREADYEXIST:
printf(" Some components must not be duplicated\n");
break;
default:
printf(" Unknown error cause %d\n", status);
}
}
//---------------------------------------------------------------------------
void print_state(uint8_t state)
{
//---------------------------------------------------------------------------
switch(state) {
case NAS_IDLE:
printf("NAS_IDLE\n");
return;
// case NAS_STATE_CONNECTED:printf("NAS_STATE_CONNECTED\n");return;
// case NAS_STATE_ESTABLISHMENT_REQUEST:printf("NAS_STATE_ESTABLISHMENT_REQUEST\n");return;
// case NAS_STATE_ESTABLISHMENT_FAILURE:printf("NAS_STATE_ESTABLISHMENT_FAILURE\n");return;
// case NAS_STATE_RELEASE_FAILURE:printf("NAS_STATE_RELEASE_FAILURE\n");return;
case NAS_CX_FACH:
printf("NAS_CX_FACH\n");
return;
case NAS_CX_DCH:
printf("NAS_CX_DCH\n");
return;
case NAS_CX_RECEIVED:
printf("NAS_CX_RECEIVED\n");
return;
case NAS_CX_CONNECTING:
printf("NAS_CX_CONNECTING\n");
return;
case NAS_CX_RELEASING:
printf("NAS_CX_RELEASING\n");
return;
case NAS_CX_CONNECTING_FAILURE:
printf("NAS_CX_CONNECTING_FAILURE\n");
return;
case NAS_CX_RELEASING_FAILURE:
printf("NAS_CX_RELEASING_FAILURE\n");
return;
case NAS_RB_ESTABLISHING:
printf("NAS_RB_ESTABLISHING\n");
return;
case NAS_RB_RELEASING:
printf("NAS_RB_RELEASING\n");
return;
default:
printf(" Unknown state\n");
}
}
//---------------------------------------------------------------------------
void print_usage_class()
{
//---------------------------------------------------------------------------
printf("Usage: gioctl class add {send <lcr>|receive} -f {qos <rab_id>|del|ctl|dc} -cr <classref> [-dscp <dscp>] [-ip {6|4} <saddr> <splen> <daddr> <dplen>] [-p {tcp|udp|icmp4|icmp6} <sport> <dport>]\n");
printf("Usage: gioctl class del {send <lcr>|receive} -cr <classref> [-dscp <dscp>] \n");
printf("Usage: gioctl class list {send <lcr>|receive} [-dscp <dscp>]\n");
}
//---------------------------------------------------------------------------
void print_usage_cx()
{
//---------------------------------------------------------------------------
printf("Usage: gioctl cx add <lcr> <cellid>\n");
printf("Usage: gioctl cx del <lcr>\n");
printf("Usage: gioctl cx list\n");
}
//---------------------------------------------------------------------------
void print_usage_rb()
{
//---------------------------------------------------------------------------
printf("Usage: gioctl rb add <lcr> <rab_id> <qos>\n");
printf("Usage: gioctl rb list <lcr>\n");
}
//---------------------------------------------------------------------------
int main(int argc, char *argv[])
{
//---------------------------------------------------------------------------
struct nas_ioctl gifr;
int err, fd;
// Invalid number of arguments
if (argc<2) {
printf("Usage: gioctl statistic\n");
print_usage_cx();
print_usage_rb();
print_usage_class();
return -1;
}
// Get an UDP IPv6 socket ??
fd=socket(AF_INET6, SOCK_DGRAM, 0);
if (fd<0) {
printf("Error opening socket\n");
return 0;
}
strcpy(gifr.name, "oai0");
printf("Socket opened successfully\n");
/***************************/
if (strcmp(argv[1], "statistic")==0) {
struct nas_msg_statistic_reply *msgrep;
gifr.type=NAS_MSG_STATISTIC_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep));
msgrep=(struct nas_msg_statistic_reply *)(gifr.msg);
printf(" Statistics requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets);
printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes);
printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors);
printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped);
return 0;
}
/***************************/
if (strcmp(argv[1], "cx")==0) {
if (argc<3) {
print_usage_cx();
return -1;
}
/***/
// printf("Usage: gioctl cx add <lcr> <cellid>\n");
if (strcmp(argv[2], "add")==0) {
struct nas_msg_cx_establishment_request *msgreq;
struct nas_msg_cx_establishment_reply *msgrep;
if (argc<5) {
print_usage_cx();
return -1;
}
gifr.type=NAS_MSG_CX_ESTABLISHMENT_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_cx_establishment_request *)(gifr.msg);
msgrep=(struct nas_msg_cx_establishment_reply *)(gifr.msg);
msgreq->lcr=strtoul(argv[3], NULL, 0);
msgreq->cellid=strtoul(argv[4], NULL, 0);
//
printf(" Connection establishment requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
perror("Connection establishment IOCTL error\n");
return -1;
}
if (msgrep->status<0) {
printf(" Connexion establishment failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
// printf("Usage: gioctl cx del <lcr>\n");
if (strcmp(argv[2], "del")==0) {
struct nas_msg_cx_release_request *msgreq;
struct nas_msg_cx_release_reply *msgrep;
if (argc<4) {
print_usage_cx();
return -1;
}
gifr.type=NAS_MSG_CX_RELEASE_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_cx_release_request *)(gifr.msg);
msgrep=(struct nas_msg_cx_release_reply *)(gifr.msg);
msgreq->lcr=strtoul(argv[3], NULL, 0);
//
printf(" Connexion release requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
if (msgrep->status<0) {
printf(" Connexion release failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
// printf("Usage: gioctl cx list\n");
if (strcmp(argv[2], "list")==0) {
uint8_t *msgrep;
uint8_t i;
struct nas_msg_cx_list_reply *list;
uint8_t lcr;
gifr.type=NAS_MSG_CX_LIST_REQUEST;
gifr.msg=(char *)malloc(NAS_LIST_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1);
msgrep=(uint8_t *)(gifr.msg);
//
printf(" Connexion list requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
printf("Lcr\t\tCellId\tIID4\tIID6\t\t\tnrb\tnsclass\tState\n");
list=(struct nas_msg_cx_list_reply *)(msgrep+1);
for(lcr=0; lcr<msgrep[0]; ++lcr) {
printf("%u\t\t%u\t%u\t", list[lcr].lcr, list[lcr].cellid, list[lcr].iid4);
for (i=0; i<8; ++i)
printf("%02x", *((uint8_t *)list[lcr].iid6+i));
printf("\t%u\t%u\t", list[lcr].num_rb, list[lcr].nsclassifier);
print_state(list[lcr].state);
}
return 0;
}
print_usage_cx();
return -1;
}
/***************************/
if (strcmp(argv[1], "rb")==0) {
if (argc<3) {
print_usage_rb();
return -1;
}
/***/
// printf("Usage: gioctl rb add <lcr> <rab_id> <qos>\n");
if (strcmp(argv[2], "add")==0) {
struct nas_msg_rb_establishment_request *msgreq;
struct nas_msg_rb_establishment_reply *msgrep;
if (argc<6) {
print_usage_rb();
return -1;
}
gifr.type=NAS_MSG_RB_ESTABLISHMENT_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_rb_establishment_request *)(gifr.msg);
msgrep=(struct nas_msg_rb_establishment_reply *)(gifr.msg);
msgreq->lcr=strtoul(argv[3], NULL, 0);
msgreq->rab_id=strtoul(argv[4], NULL, 0);
msgreq->qos=strtoul(argv[5], NULL, 0);
//
printf(" Radio bearer establishment requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
if (msgrep->status<0) {
printf(" Radio bearer establishment failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
if (strcmp(argv[2], "del")==0) {
struct nas_msg_rb_release_request *msgreq;
struct nas_msg_rb_release_reply *msgrep;
if (argc<5) {
print_usage_rb();
return -1;
}
gifr.type=NAS_MSG_RB_RELEASE_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_rb_release_request *)(gifr.msg);
msgrep=(struct nas_msg_rb_release_reply *)(gifr.msg);
msgreq->lcr=strtoul(argv[3], NULL, 0);
msgreq->rab_id=strtoul(argv[4], NULL, 0);
//
printf(" Radio Bearer release requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
if (msgrep->status<0) {
printf(" Radio bearer release failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
// printf("Usage: gioctl rb list <lcr>\n");
if (strcmp(argv[2], "list")==0) {
uint8_t *msgrep;
uint8_t rbi;
struct nas_msg_rb_list_reply *list;
struct nas_msg_rb_list_request *msgreq;
if (argc<4) {
print_usage_rb();
return -1;
}
gifr.type=NAS_MSG_RB_LIST_REQUEST;
gifr.msg=(char *)malloc(NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1);
msgreq=(struct nas_msg_rb_list_request *)(gifr.msg);
msgrep=(uint8_t *)(gifr.msg);
msgreq->lcr=strtoul(argv[3], NULL, 0);
//
printf(" Radio bearer list requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
printf("rab_id\t\tSapi\t\tQoS\t\tState\n");
list=(struct nas_msg_rb_list_reply *)(msgrep+1);
for(rbi=0; rbi<msgrep[0]; ++rbi) {
printf("%u\t\t%u\t\t%u\t\t", list[rbi].rab_id, list[rbi].sapi, list[rbi].qos);
print_state(list[rbi].state);
}
return 0;
}
print_usage_rb();
return -1;
}
/***************************/
if (strcmp(argv[1], "class")==0) {
if (argc<3) {
print_usage_class();
return -1;
}
/***/
if (strcmp(argv[2], "add")==0) {
struct nas_msg_class_add_request *msgreq;
struct nas_msg_class_add_reply *msgrep;
uint8_t i,j;
gifr.type=NAS_MSG_CLASS_ADD_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_class_add_request *)(gifr.msg);
msgrep=(struct nas_msg_class_add_reply *)(gifr.msg);
i=3;
if (strcmp(argv[i], "send")==0) {
msgreq->dir=NAS_DIRECTION_SEND;
msgreq->lcr=strtoul(argv[++i], NULL, 0);
++i;
} else {
if (strcmp(argv[i], "receive")==0) {
msgreq->dir=NAS_DIRECTION_RECEIVE;
++i;
} else {
print_usage_class();
return -1;
}
}
msgreq->classref=USHRT_MAX;
msgreq->dscp=NAS_DSCP_DEFAULT;
msgreq->version=NAS_VERSION_DEFAULT;
msgreq->protocol=NAS_PROTOCOL_DEFAULT;
msgreq->sport=NAS_PORT_DEFAULT;
msgreq->dport=NAS_PORT_DEFAULT;
msgreq->fct=0;
while (i<argc) {
if (strcmp(argv[i], "-cr")==0) {
msgreq->classref=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "-dscp")==0) {
msgreq->dscp=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "-f")==0) {
++i;
if (strcmp(argv[i], "qos")==0) {
msgreq->fct=NAS_FCT_QOS_SEND;
msgreq->rab_id=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "del")==0) {
msgreq->fct=NAS_FCT_DEL_SEND;
msgreq->rab_id=0;
++i;
continue;
}
if (strcmp(argv[i], "ctl")==0) {
msgreq->fct=NAS_FCT_CTL_SEND;
msgreq->rab_id=0;
++i;
continue;
}
if (strcmp(argv[i], "dc")==0) {
msgreq->fct=NAS_FCT_DC_SEND;
msgreq->rab_id=0;
++i;
continue;
}
print_usage_class();
return -1;
}
if (strcmp(argv[i], "-ip")==0) {
++i;
if (strcmp(argv[i], "4")==0) {
if (msgreq->version!=NAS_VERSION_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->version=NAS_VERSION_4;
inet_pton(AF_INET, argv[++i], (void *)(&msgreq->saddr));
msgreq->splen=strtoul(argv[++i], NULL, 0);
inet_pton(AF_INET, argv[++i], (void *)(&msgreq->daddr));
msgreq->dplen=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "6")==0) {
if (msgreq->version!=NAS_VERSION_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->version=NAS_VERSION_6;
inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->saddr));
msgreq->splen=strtoul(argv[++i], NULL, 0);
inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->daddr));
msgreq->dplen=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
print_usage_class();
return -1;
}
if (strcmp(argv[i], "-p")==0) {
++i;
if (strcmp(argv[i], "tcp")==0) {
if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->protocol=NAS_PROTOCOL_TCP;
msgreq->sport=strtoul(argv[++i], NULL, 0);
msgreq->dport=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "udp")==0) {
if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->protocol=NAS_PROTOCOL_UDP;
msgreq->sport=strtoul(argv[++i], NULL, 0);
msgreq->dport=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "icmp4")==0) {
if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->protocol=NAS_PROTOCOL_ICMP4;
msgreq->sport=strtoul(argv[++i], NULL, 0);
msgreq->dport=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "icmp6")==0) {
if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) {
print_usage_class();
return -1;
}
msgreq->protocol=NAS_PROTOCOL_ICMP6;
msgreq->sport=strtoul(argv[++i], NULL, 0);
msgreq->dport=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
print_usage_class();
return -1;
}
print_usage_class();
return -1;
}
if ((msgreq->classref==USHRT_MAX)||(msgreq->fct==0)) {
print_usage_class();
return -1;
}
printf(" Class add requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
if (msgrep->status<0) {
printf(" Class add failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
if (strcmp(argv[2], "del")==0) {
uint8_t i;
struct nas_msg_class_del_request *msgreq;
struct nas_msg_class_del_reply *msgrep;
gifr.type=NAS_MSG_CLASS_DEL_REQUEST;
gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep));
msgreq=(struct nas_msg_class_del_request *)(gifr.msg);
msgrep=(struct nas_msg_class_del_reply *)(gifr.msg);
i=3;
if (strcmp(argv[i], "send")==0) {
msgreq->dir=NAS_DIRECTION_SEND;
msgreq->lcr=strtoul(argv[++i], NULL, 0);
++i;
} else {
if (strcmp(argv[i], "receive")==0) {
msgreq->dir=NAS_DIRECTION_RECEIVE;
++i;
} else {
print_usage_class();
return -1;
}
}
msgreq->classref=USHRT_MAX;
msgreq->dscp=NAS_DSCP_DEFAULT;
while (i<argc) {
if (strcmp(argv[i], "-cr")==0) {
msgreq->classref=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
if (strcmp(argv[i], "-dscp")==0) {
msgreq->dscp=strtoul(argv[++i], NULL, 0);
++i;
continue;
}
print_usage_class();
return -1;
}
if (msgreq->classref==USHRT_MAX) {
print_usage_class();
return -1;
}
printf(" Class del requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
if (msgrep->status<0) {
printf(" Class add failure: ");
print_error(msgrep->status);
return -1;
}
return 0;
}
/***/
if (strcmp(argv[2], "list")==0) {
uint8_t *msgrep;
uint8_t cli, i;
struct nas_msg_class_list_reply *list;
struct nas_msg_class_list_request *msgreq;
char addr[45];
if (argc<4) {
print_usage_class();
return -1;
}
gifr.type=NAS_MSG_CLASS_LIST_REQUEST;
gifr.msg=(char *)malloc(NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1);
if (gifr.msg==NULL) {
printf(" No memory\n");
return -1;
}
msgreq=(struct nas_msg_class_list_request *)(gifr.msg);
msgrep=(uint8_t *)(gifr.msg);
i=3;
if (strcmp(argv[i], "send")==0) {
msgreq->dir=NAS_DIRECTION_SEND;
msgreq->lcr=strtoul(argv[++i], NULL, 0);
++i;
} else {
if (strcmp(argv[i], "receive")==0) {
msgreq->dir=NAS_DIRECTION_RECEIVE;
msgreq->lcr=0;
++i;
} else {
print_usage_class();
return -1;
}
}
msgreq->dscp=NAS_DSCP_DEFAULT;
while (i<argc) {
if (strcmp(argv[i], "-dscp")==0)
msgreq->dscp=strtoul(argv[++i], NULL, 0);
}
printf(" Classifier list requested\n");
err=ioctl(fd, NASMT_IOCTL_RAL, &gifr);
//
if (err<0) {
printf("IOCTL error, err=%d\n",err);
return -1;
}
printf("Lcr\trab_id\tCref\tFct\t(Vers., saddr, daddr)\t\t\t\t(Proto., Sport, Dport)\n");
list=(struct nas_msg_class_list_reply *)(msgrep+1);
for(cli=0; cli<msgrep[0]; ++cli) {
printf("%u\t%u\t%u\t", list[cli].lcr, list[cli].rab_id, list[cli].classref);
switch(list[cli].fct) {
case NAS_FCT_QOS_SEND:
printf("qos\t");
break;
case NAS_FCT_DEL_SEND:
printf("del\t");
break;
case NAS_FCT_CTL_SEND:
printf("ctl\t");
break;
case NAS_FCT_DC_SEND:
printf("dc\t");
break;
default:
printf("?\t");
}
switch(list[cli].version) {
case 4:
inet_ntop(AF_INET, (void *)&list[cli].saddr, addr, 45);
printf("(ip4, %s/%u,", addr, list[cli].splen);
inet_ntop(AF_INET, (void *)&list[cli].daddr, addr, 45);
printf("%s/%u\t", addr, list[cli].dplen);
break;
case 6:
inet_ntop(AF_INET6, (void *)&list[cli].saddr, addr, 45);
printf("(ip6, %s/%u", addr, list[cli].splen);
inet_ntop(AF_INET6, (void *)&list[cli].daddr, addr, 45);
printf("%s/%u\t", addr, list[cli].dplen);
break;
default:
printf("(--, --, --)\t\t\t");
break;
}
switch(list[cli].protocol) {
case IPPROTO_UDP:
printf("(udp, %u, %u)\t\n", list[cli].sport, list[cli].dport);
break;
case IPPROTO_TCP:
printf("(tcp, %u, %u)\t\n", list[cli].sport, list[cli].dport);
break;
case IPPROTO_ICMP:
printf("(icmp4, %u, %u)\t\n", list[cli].sport, list[cli].dport);
break;
case IPPROTO_ICMPV6:
printf("(icmp6, %u, %u)\t\n", list[cli].sport, list[cli].dport);
break;
default:
printf("(--, --, --)\t\n");
}
}
return 0;
}
return 0;
}
printf(" Unknown command %s\n",argv[1]);
return 0;
}
@@ -1,49 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _IOCTL_H
#define _IOCTL_H
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/if.h>
#include <linux/ipv6.h>
#include <linux/in.h>
#include <linux/in6.h>
//#include <linux/netdevice.h>
//#include <graal_constant.h>
//#define GRAAL_STATE_IDLE 0
//#define GRAAL_STATE_CONNECTED 1
//#define GRAAL_STATE_ESTABLISHMENT_REQUEST 2
//#define GRAAL_STATE_ESTABLISHMENT_FAILURE 3
//#define GRAAL_STATE_RELEASE_FAILURE 4
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
extern int inet_pton(int af, const char *src, void *dst);
extern char *inet_ntop(int af, const void *src, char *dst, size_t sise);
#endif //_IOCTL_H
@@ -1,79 +0,0 @@
# NAS CELLULAR Driver makefile
#
include $(OPENAIR_DIR)/common/utils/Makefile.inc
NAS_UPDIR := $(shell /bin/pwd)
####################################################
# D E B U G F L A G S
####################################################
####################################################
# EXTRA COMPILER FLAGS
####################################################
EXTRA_CFLAGS = -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,)
ifdef ADDRCONF
EXTRA_CFLAGS += -DADDRCONF
endif
ifdef NAS_DRIVER_TYPE_ETHERNET
EXTRA_CFLAGS += -DNAS_DRIVER_TYPE_ETHERNET
endif
ifdef PDCP_USE_NETLINK
EXTRA_CFLAGS += -DPDCP_USE_NETLINK
else
EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall
endif
ifdef LOOPBACK
EXTRA_CFLAGS += -DLOOPBACK_TEST
endif
ifdef ADDRESS_FIX
EXTRA_CFLAGS += -DNAS_ADDRESS_FIX
endif
####################################################
# NASMTCELL extra compilation flags
####################################################
#RTAI=1
RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR
EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_MT
####################################################
# LOADABLE MODULE GOALS
####################################################
obj-m += nascellmt.o
nascellmt-objs += nasmt_device.o
nascellmt-objs += nasmt_common.o
nascellmt-objs += nasmt_iocontrol.o
nascellmt-objs += nasmt_classifier.o
nascellmt-objs += nasmt_tool.o
nascellmt-objs += nasmt_ascontrol.o
ifdef PDCP_USE_NETLINK
nascellmt-objs += nasmt_netlink.o
endif
####################################################
# REVOIR LE CLEAN
####################################################
#netlink.ko:
#make $(x)$(y) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR) M=`pwd` modules
#nasmesh.ko:
# make V=1 -C $(KERNEL_DIR) M=`pwd` modules
print:
@echo subversion : $(SUBVERSION)
@echo RRC_DIR $(RRC_DIR)
clean:
rm -f *.ko
rm -f .*.ko.cmd
rm -f .*.o.cmd
rm -f *.o
rm -f *.mod.c
find . -name *.ko -delete
find . -name *.o -delete
find . -name *.mod.c -delete
File diff suppressed because it is too large Load Diff
@@ -1,884 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_classifier.c
* \brief Flow classification functions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasmt_variables.h"
#include "nasmt_proto.h"
#include <net/ip6_fib.h>
#include <net/route.h>
#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
/* Address to accept any incoming messages. */
#define INADDR_ANY ((unsigned long int) 0x00000000)
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), \
ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), \
ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), \
ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), \
ntohs((addr)->s6_addr16[7])
#define IN6_IS_ADDR_UNSPECIFIED(a) \
(((__const uint32_t *) (a))[0] == 0 \
&& ((__const uint32_t *) (a))[1] == 0 \
&& ((__const uint32_t *) (a))[2] == 0 \
&& ((__const uint32_t *) (a))[3] == 0)
#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \
(((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \
&& ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \
&& ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \
&& ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3]))))
#define IN_ARE_ADDR_MASKED_EQUAL(a,b,m) \
(((((__const uint8_t *) (a))[0] & (((__const uint8_t *) (m))[0])) == (((__const uint8_t *) (b))[0] & (((__const uint8_t *) (m))[0]))) \
&& ((((__const uint8_t *) (a))[1] & (((__const uint8_t *) (m))[1])) == (((__const uint8_t *) (b))[1] & (((__const uint8_t *) (m))[1]))) \
&& ((((__const uint8_t *) (a))[2] & (((__const uint8_t *) (m))[2])) == (((__const uint8_t *) (b))[2] & (((__const uint8_t *) (m))[2]))) \
&& ((((__const uint8_t *) (a))[3] & (((__const uint8_t *) (m))[3])) == (((__const uint8_t *) (b))[3] & (((__const uint8_t *) (m))[3]))))
//---------------------------------------------------------------------------
void nasmt_create_mask_ipv6_addr(struct in6_addr *masked_addrP, int prefix_len)
{
//---------------------------------------------------------------------------
int u6_addr8_index;
int u6_addr1_index;
int index;
masked_addrP->s6_addr32[0] = 0xFFFFFFFF;
masked_addrP->s6_addr32[1] = 0xFFFFFFFF;
masked_addrP->s6_addr32[2] = 0xFFFFFFFF;
masked_addrP->s6_addr32[3] = 0xFFFFFFFF;
u6_addr8_index = prefix_len >> 3;
u6_addr1_index = prefix_len & 0x07;
for (index = u6_addr8_index + 1; index < 16; index++) {
masked_addrP->s6_addr[index] = 0;
}
if (u6_addr1_index > 0) {
masked_addrP->s6_addr[u6_addr8_index] = 0xFF << (8-u6_addr1_index);
}
}
//---------------------------------------------------------------------------
void nasmt_create_mask_ipv4_addr(struct in_addr *masked_addrP, int prefix_len)
{
//---------------------------------------------------------------------------
if (prefix_len > 32) {
prefix_len = 32;
}
masked_addrP->s_addr = 0xFFFFFFFF << (32 - prefix_len);
return;
}
//---------------------------------------------------------------------------
// Add a new classifier rule (send direction)
struct classifier_entity *nasmt_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref)
{
//---------------------------------------------------------------------------
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_sclassifier: begin for dscp %d, classref %d\n", dscp,classref);
#endif
if (cx==NULL) {
printk("nasmt_CLASS_add_sclassifier - input parameter cx is NULL \n");
return NULL;
}
//***
for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next) {
if (gc->classref==classref) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_sclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
}
gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_ATOMIC);
if (gc==NULL)
return NULL;
memset(gc, 0, sizeof(struct classifier_entity));
gc->next=cx->sclassifier[dscp];
gc->classref=classref;
cx->sclassifier[dscp]=gc;
++cx->nsclassifier;
++gpriv->next_sclassref; //increment send classref index - MW 15/01/07
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_sclassifier: classifier created for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
//---------------------------------------------------------------------------
// Add a new classifier rule (receive direction)
struct classifier_entity *nasmt_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref)
{
//---------------------------------------------------------------------------
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_rclassifier: begin\n");
#endif
//***
for (gc=gpriv->rclassifier[dscp]; gc!=NULL; gc=gc->next) {
if (gc->classref==classref) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_rclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
}
gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL);
if (gc==NULL)
return NULL;
gc->next=gpriv->rclassifier[dscp];
gc->classref=classref;
gpriv->rclassifier[dscp]=gc;
++gpriv->nrclassifier;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_add_rclassifier: classifier created for dscp %d, classref %d\n",dscp,classref);
#endif
return gc;
}
//---------------------------------------------------------------------------
void nasmt_CLASS_flush_sclassifier(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
uint8_t dscpi;
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_flush_sclassifier: begin\n");
#endif
if (cx==NULL) {
printk("nasmt_CLASS_flush_sclassifier - input parameter cx is NULL \n");
return;
}
//***
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
for (gc=cx->sclassifier[dscpi]; gc!=NULL; gc=cx->sclassifier[dscpi]) {
cx->sclassifier[dscpi]=gc->next;
kfree(gc);
}
}
cx->nsclassifier=0;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_flush_sclassifier: end\n");
#endif
}
//---------------------------------------------------------------------------
void nasmt_CLASS_flush_rclassifier()
{
//---------------------------------------------------------------------------
uint8_t dscpi;
struct classifier_entity *gc;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_flush_rclassifier: begin\n");
#endif
//***
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
for (gc=gpriv->rclassifier[dscpi]; gc!=NULL; gc=gpriv->rclassifier[dscpi]) {
gpriv->rclassifier[dscpi]=gc->next;
kfree(gc);
}
}
gpriv->nrclassifier=0;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_flush_rclassifier: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete a classifier rule (send direction)
void nasmt_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref)
{
//---------------------------------------------------------------------------
struct classifier_entity *p,*np;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_del_sclassifier: begin\n");
#endif
if (cx==NULL) {
printk("nasmt_CLASS_del_sclassifier - input parameter cx is NULL \n");
return;
}
//***
p=cx->sclassifier[dscp];
if (p==NULL)
return;
if (p->classref==classref) {
cx->sclassifier[dscp]=p->next;
kfree(p);
--cx->nsclassifier;
return;
}
for (np=p->next; np!=NULL; p=np) {
if (np->classref==classref) {
p->next=np->next;
kfree(np);
--cx->nsclassifier;
return;
}
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_del_sclassifier: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete a classifier rule (receive direction)
void nasmt_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref)
{
//---------------------------------------------------------------------------
struct classifier_entity *p,*np;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_del_rclassifier: begin\n");
#endif
//***
p=gpriv->rclassifier[dscp];
if (p==NULL)
return;
if (p->classref==classref) {
gpriv->rclassifier[dscp]=p->next;
kfree(p);
--gpriv->nrclassifier;
return;
}
for (np=p->next; np!=NULL; p=np) {
if (np->classref==classref) {
p->next=np->next;
kfree(np);
--gpriv->nrclassifier;
return;
}
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_del_rclassifier: end\n");
#endif
}
/* ORIGINAL VERSION
//---------------------------------------------------------------------------
// Search the entity with the IPv6 address 'addr'
struct cx_entity *nasmt_CLASS_cx6(struct sk_buff *skb){
//---------------------------------------------------------------------------
uint8_t cxi;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx6: begin\n");
#endif
cxi=0;
return gpriv->cx+cxi;
}*/
//---------------------------------------------------------------------------
// Search the entity with the IPv6 address 'addr'
// Navid: the ipv6 classifier is not fully tested
struct cx_entity *nasmt_CLASS_cx6(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index)
{
//---------------------------------------------------------------------------
uint8_t cxi;
struct cx_entity *cx = NULL;
struct classifier_entity *sclassifier= NULL;
uint32_t mc_addr_hdr;
struct in6_addr masked_addr;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx6: begin\n");
#endif
if (skb) {
#ifdef NAS_DEBUG_CLASS
printk("SOURCE ADDR %X:%X:%X:%X:%X:%X:%X:%X",NIP6ADDR(&(ipv6_hdr(skb)->saddr)));
printk(" DEST ADDR %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&(ipv6_hdr(skb)->daddr)));
#endif
mc_addr_hdr = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0]);
// First check if multicast [1st octet is FF]
if ((mc_addr_hdr & 0xFF000000) == 0xFF000000) {
// packet type according to the scope of the multicast packet
// we don't consider RPT bits in second octet [maybe done later if needed]
switch(mc_addr_hdr & 0x000F0000) {
case (0x00020000):
*paddr_type = NAS_IPV6_ADDR_MC_SIGNALLING;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx6: multicast packet - signalling \n");
#endif
break;
default:
printk("nasmt_CLASS_cx6: default multicast\n");
*paddr_type = NAS_IPV6_ADDR_UNKNOWN;
}
} else {
// This is not multicast, so we should be able to identify the MT
*paddr_type = NAS_IPV6_ADDR_UNICAST;
cxi = 0;
(*cx_index)++;
sclassifier = gpriv->cx[cxi].sclassifier[dscp];
while (sclassifier!=NULL) {
// verify that this is an IPv6 classifier
if ((sclassifier->version == NAS_VERSION_6) || (sclassifier->version == NAS_VERSION_DEFAULT)) {
/*LGif (IN6_IS_ADDR_UNSPECIFIED(&(sclassifier->daddr.ipv6))) {
printk("nas_CLASS_cx6: addr is null \n");
sclassifier = sclassifier->next;
continue;
}*/
#ifdef NAS_DEBUG_CLASS
printk("cx %d : DSCP %d %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, dscp, NIP6ADDR(&(sclassifier->daddr.ipv6)));
#endif //NAS_DEBUG_CLASS
//if ((dst = (unsigned int*)&(((struct rt6_info *)skbdst)->rt6i_gateway)) == 0){
// LG: STRANGE
if (IN6_IS_ADDR_UNSPECIFIED(&ipv6_hdr(skb)->daddr)) {
printk("nasmt_CLASS_cx6: dst addr is null \n");
sclassifier = sclassifier->next;
continue;
}
nasmt_create_mask_ipv6_addr(&masked_addr, sclassifier->dplen);
// Modified MW to check only the iid6
masked_addr.s6_addr32[0] = 0x00000000;
masked_addr.s6_addr32[1] = 0x00000000;
if (IN6_ARE_ADDR_MASKED_EQUAL(&ipv6_hdr(skb)->daddr, &(sclassifier->daddr.ipv6), &masked_addr)) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx6: found cx %d: %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, NIP6ADDR(&(sclassifier->daddr.ipv6)));
#endif //NAS_DEBUG_CLASS
return &gpriv->cx[cxi];
}
}
// Go to next classifier entry for connection
sclassifier = sclassifier->next;
}
}
}
//printk("nas_CLASS_cx6 NOT FOUND: %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&ipv6_hdr(skb)->daddr));
return cx;
}
/* ORIGINAL VERSION
//---------------------------------------------------------------------------
// Search the entity with the IPv4 address 'addr'
struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb){
//---------------------------------------------------------------------------
uint8_t cxi;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx4: begin\n");
#endif
cxi=0;
return gpriv->cx+cxi;
}*/
//---------------------------------------------------------------------------
// Search the entity with the IPv4 address 'addr'
struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index)
{
//---------------------------------------------------------------------------
unsigned char cxi;
uint32_t daddr;
struct cx_entity *cx=NULL;
struct classifier_entity *pclassifier=NULL;
struct in_addr masked_addr;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx4: begin\n");
#endif
if (skb!=NULL) {
daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr;
if (daddr != INADDR_ANY) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx4: SOURCE ADDR %d.%d.%d.%d",NIPADDR(ip_hdr(skb)->saddr));
printk(" DEST ADDR %d.%d.%d.%d\n",NIPADDR(ip_hdr(skb)->daddr));
#endif
if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
// TO BE CHECKED
*paddr_type = NAS_IPV4_ADDR_MC_SIGNALLING;
} else {
if (ipv4_is_lbcast(ip_hdr(skb)->daddr)) {
// TO BE CHECKED
*paddr_type = NAS_IPV4_ADDR_BROADCAST;
} else {
if (IN_CLASSA(ip_hdr(skb)->daddr) || IN_CLASSB(ip_hdr(skb)->daddr) || IN_CLASSC(ip_hdr(skb)->daddr)) {
*paddr_type = NAS_IPV4_ADDR_UNICAST;
cxi = 0;
(*cx_index)++;
pclassifier = gpriv->cx[cxi].sclassifier[dscp];
while (pclassifier!=NULL) {
// verify that this is an IPv4 classifier
if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) {
nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen);
if (IN_ARE_ADDR_MASKED_EQUAL(&ip_hdr(skb)->daddr, &(pclassifier->daddr.ipv4), &masked_addr)) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_cx4: IP MASK MATCHED: found cx %d: %d.%d.%d.%d/%d\n",cxi, NIPADDR(pclassifier->daddr.ipv4), pclassifier->dplen);
#endif
return &gpriv->cx[cxi];
}
}
// goto to next classification rule for the connection
pclassifier = pclassifier->next;
}
} else {
*paddr_type = NAS_IPV4_ADDR_UNKNOWN;
}
}
}
}
}
return cx;
}
//---------------------------------------------------------------------------
// Search the sending function for IP Packet
void nasmt_CLASS_send(struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct classifier_entity *pclassifier, *sp;
uint8_t *protocolh = NULL;
uint8_t version;
uint8_t protocol, dscp;
uint16_t classref;
struct cx_entity *cx;
#ifdef NAS_DEBUG_CLASS
char sfct[10], sprotocol[10];
#endif
struct net_device *dev = gdev;
unsigned char cx_index,no_connection;
int addr_type;
struct in6_addr masked6_addr;
struct in_addr masked_addr;
// RARP vars
struct arphdr *rarp;
unsigned char *rarp_ptr;
/* s for "source", t for "target" */
__be32 sip, tip;
unsigned char *sha, *tha;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: begin -\n");
#endif
if (skb==NULL) {
printk("nasmt_CLASS_send - input parameter skb is NULL \n");
return;
}
//***
#ifdef NAS_DEBUG_SEND
printk("nasmt_CLASS_send - Received IP packet to transmit:");
if ((skb->data) != NULL) {
if (skb->len<100)
nasmt_TOOL_print_buffer(skb->data,skb->len);
else
nasmt_TOOL_print_buffer(skb->data,100);
}
#endif
//***
// find all connections related to socket
cx_index = 0;
no_connection = 1;
cx = NULL;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: [before switch on IP protocol version] \n");
#endif
// Get mobile connexion entity, protocol and dscp from IP packet
switch (ntohs(skb->protocol)) {
case ETH_P_IPV6:
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : skb->protocol : IPv6 \n");
#endif
version = NAS_VERSION_6;
addr_type = NAS_IPV6_ADDR_UNKNOWN;
protocolh = nasmt_TOOL_get_protocol6(ipv6_hdr(skb), &protocol);
dscp = nasmt_TOOL_get_dscp6 (ipv6_hdr(skb));
cx = nasmt_CLASS_cx6 (skb, dscp, &addr_type, &cx_index);
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send - ETH_P_IPV6 skb %p dscp %d gpriv %p cx_index %p \n",skb, dscp, gpriv, &cx_index);
#endif
// find in default DSCP a valid classification
if (cx == NULL) {
switch (addr_type) {
case NAS_IPV6_ADDR_MC_SIGNALLING:
case NAS_IPV6_ADDR_UNICAST:
pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT];
while (pclassifier!=NULL) {
if ((pclassifier->version == NAS_VERSION_6) || (pclassifier->version == NAS_VERSION_DEFAULT)) {
// ok found default classifier for this packet
nasmt_create_mask_ipv6_addr(&masked6_addr, pclassifier->dplen);
if (IN6_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv6, &ipv6_hdr(skb)->daddr, &masked6_addr)) {
// then force dscp
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen);
#endif
dscp = NAS_DSCP_DEFAULT;
break;
} else {
if(IN6_IS_ADDR_UNSPECIFIED(&pclassifier->daddr.ipv6)) {
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_IS_ADDR_UNSPECIFIED\n");
#endif
dscp = NAS_DSCP_DEFAULT;
break;
}
}
}
pclassifier = pclassifier->next;
}
break;
// should have found a valid classification rule
case NAS_IPV6_ADDR_UNKNOWN:
default:
printk("nasmt_CLASS_send: No corresponding address type\n");
}
}
break;
case ETH_P_ARP:
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : skb->protocol : ARP \n");
#endif
version = NAS_VERSION_4;
addr_type = NAS_IPV4_ADDR_BROADCAST;
dscp = 0;
cx = NULL;
// Basic sanity checks can be done without the lock
rarp = (struct arphdr *)skb_network_header(skb);
if (rarp) {
if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
printk("nasmt_CLASS_send: ARP PACKET WRONG ADDR LEN or WRONG ARP HEADER TYPE\n");
break;
}
} else {
printk("nasmt_CLASS_send: ARP HEADER POINTER IS NULL\n");
break;
}
// If it's not Ethernet, delete it.
if (rarp->ar_pro != htons(ETH_P_IP)) {
printk("nasmt_CLASS_send: ARP PACKET PROTOCOL IS NOT ETHERNET\n");
break;
}
rarp_ptr = (unsigned char *) (rarp + 1);
sha = rarp_ptr;
rarp_ptr += dev->addr_len;
memcpy(&sip, rarp_ptr, 4);
rarp_ptr += 4;
tha = rarp_ptr;
rarp_ptr += dev->addr_len;
memcpy(&tip, rarp_ptr, 4);
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: ARP DEST IP transport IP = %d.%d.%d.%d\n",NIPADDR(tip));
#endif
pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT];
while (pclassifier!=NULL) {
if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) {
// ok found default classifier for this packet
nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen);
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: MASK = %d.%d.%d.%d\n",NIPADDR(masked_addr.s_addr));
#endif
//
if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &tip, &masked_addr.s_addr)) {
// then force dscp
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n", pclassifier->dplen);
#endif
dscp = NAS_DSCP_DEFAULT;
break;
} else {
if (INADDR_ANY == pclassifier->daddr.ipv4) {
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n");
#endif
dscp = NAS_DSCP_DEFAULT;
break;
}
}
}
pclassifier = pclassifier->next;
}
break;
case ETH_P_IP:
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : skb->protocol : IPv4 \n");
#endif
version = NAS_VERSION_4;
addr_type = NAS_IPV4_ADDR_UNKNOWN;
dscp = nasmt_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb)));
cx = nasmt_CLASS_cx4(skb, dscp, &addr_type, &cx_index);
protocolh = nasmt_TOOL_get_protocol4((struct iphdr *)(skb_network_header(skb)), &protocol);
// find in default DSCP a valid classification
if (cx == NULL) {
switch (addr_type) {
case NAS_IPV4_ADDR_MC_SIGNALLING:
case NAS_IPV4_ADDR_UNICAST:
case NAS_IPV4_ADDR_BROADCAST:
pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT];
while (pclassifier != NULL) {
if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) {
// ok found default classifier for this packet
nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen);
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : MASK = %d.%d.%d.%d\n", NIPADDR(masked_addr.s_addr));
#endif
if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &ip_hdr(skb)->daddr, &masked_addr.s_addr)) {
// then force dscp
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen);
#endif
dscp = NAS_DSCP_DEFAULT;
break;
} else {
if(INADDR_ANY == pclassifier->daddr.ipv4) {
cx = &gpriv->cx[0];
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n");
#endif
dscp = NAS_DSCP_DEFAULT;
break;
}
}
}
pclassifier = pclassifier->next;
}
break;
// should have found a valid classification rule
case NAS_IPV4_ADDR_UNKNOWN:
default:
printk("nasmt_CLASS_send: No corresponding address type\n");
}
}
#ifdef NAS_DEBUG_CLASS
//printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %08X\n",ntohs(skb->protocol),dscp,cx);
if (cx)
printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %d\n",ntohs(skb->protocol),dscp,cx->lcr);
else
printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, No valid connection\n",ntohs(skb->protocol),dscp);
#endif
break;
default:
printk("nasmt_CLASS_send: Unknown IP version protocol\n");
version = 0;
return;
}
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasmt_CLASS_send: [before if (cx != NULL)]\n");
#endif
// If a valid connection for the DSCP/EXP with destination address
// is found scan all protocol-based classification rules
if (cx != NULL) {
classref = 0;
sp = NULL;
if (cx->state!=NAS_CX_DCH) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: UE not connected, in state %d. Packet is dropped\n",cx->state);
#endif
return;
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: DSCP %d version %d: looking for classifier entry\n",dscp, version);
#endif
for (pclassifier=cx->sclassifier[dscp]; pclassifier!=NULL; pclassifier=pclassifier->next) {
#ifdef NAS_DEBUG_CLASS
printk("nasmt_CLASS_send: DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,pclassifier->classref,pclassifier->protocol,pclassifier->version);
#endif
// normal rule checks that network protocol version matches
if ((pclassifier->version == version) || (pclassifier->version == NAS_VERSION_DEFAULT)) {
//printk("nasmt_CLASS_send: IP version are equals\n");
sp=pclassifier;
classref=sp->classref;
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasmt_CLASS_send: classifier found for dscp %u \n", dscp);
#endif
break;
}
}
if (sp!=NULL) {
#ifdef NAS_DEBUG_CLASS
//char sfct[10], sprotocol[10];
// classifier entity found. Print its parameters
if (sp->fct==nasmt_COMMON_QOS_send)
strcpy(sfct, "data xfer");
if (sp->fct==nasmt_CTL_send)
strcpy(sfct, "iocontrol");
if (sp->fct==nasmt_COMMON_del_send)
strcpy(sfct, "delete");
if (sp->fct==nasmt_ASCTL_DC_send_sig_data_request)
strcpy(sfct, "DC-SAP");
switch(protocol) {
case NAS_PROTOCOL_UDP:
strcpy(sprotocol, "udp");
printk("udp packet\n");
break;
case NAS_PROTOCOL_TCP:
strcpy(sprotocol, "tcp");
printk("tcp packet\n");
break;
case NAS_PROTOCOL_ICMP4:
strcpy(sprotocol, "icmp4");
printk("icmp4 packet\n");
break;
case NAS_PROTOCOL_ICMP6:
strcpy(sprotocol, "icmp6");
nasmt_TOOL_pk_icmp6((struct icmp6hdr*)protocolh);
break;
default:
strcpy(sprotocol, "other L4");
break;
}
printk("nasmt_CLASS_send: (dscp %u, %s) received, (classref %u, fct %s, drb_id %u) classifier rule\n",
dscp, sprotocol, sp->classref, sfct, sp->rab_id);
#endif
//forward packet to the correct entity
if (sp->fct!=NULL) {
sp->fct(skb, cx, sp);
} else {
printk("\n\nnasmt_CLASS_send: ERROR : CLASSIFIER FUNCTION IS NULL\n\n");
}
no_connection = 0;
// end : if classifier entry match found
} else {
printk("nasmt_CLASS_send: no corresponding item in the classifier list, so the message is dropped\n");
printk("nasmt_CLASS_send: packet parameters: dscp %u, %s\n", dscp, sprotocol);
nasmt_COMMON_del_send(skb, cx, NULL); // Note MW: LG has commented this line. Why?
}
} // if connection found
#ifdef NAS_DEBUG_CLASS
if (no_connection == 1) {
printk("nasmt_CLASS_send: no corresponding connection, so the message is dropped\n");
}
printk("nasmt_CLASS_send: end\n");
#endif
}
@@ -1,542 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_common.c
* \brief Common functions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasmt_variables.h"
#include "nasmt_proto.h"
#include <linux/inetdevice.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
//---------------------------------------------------------------------------
// Receive data from FIFO (QOS or DC)
//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlen, int sap){
//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlen, void *pdcp_sdu, int sap){
void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap)
{
//---------------------------------------------------------------------------
struct sk_buff *skb;
struct ipversion *ipv;
unsigned int hard_header_len;
uint16_t *p_ether_type;
uint16_t ether_type;
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: begin\n");
#endif
#ifdef PDCP_USE_NETLINK
// data_buffer is NULL if FIFOs
if (!data_buffer) {
printk("nasmt_COMMON_receive - input parameter data_buffer is NULL \n");
return;
}
#endif
skb = dev_alloc_skb( payload_length + 2 );
if(!skb) {
printk("nasmt_COMMON_receive: low on memory\n");
++gpriv->stats.rx_dropped;
return;
}
skb_reserve(skb,2);
#ifndef PDCP_USE_NETLINK
bytes_read += rtf_get(sap, skb_put(skb, payload_length), payload_length);
if (bytes_read != NAS_PDCPH_SIZE + payload_length) {
printk("nasmt_COMMON_receive: problem while reading DC sap\n");
kfree(skb->data);
dev_kfree_skb(skb);
return;
}
#else
memcpy(skb_put(skb, payload_length), data_buffer, payload_length);
bytes_read += payload_length;
#endif
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: received packet from PDCP, length %d\n", bytes_read);
#endif
skb->dev = gdev;
hard_header_len = gdev->hard_header_len;
skb->mac_header = skb->data;
skb->pkt_type = PACKET_HOST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
ipv = (struct ipversion *)&(skb->data[hard_header_len]);
switch (ipv->version) {
case 6:
#ifdef NAS_DEBUG_RECEIVE_BASIC
printk("nasmt_COMMON_receive: receive IPv6 message\n");
#endif
skb->network_header = &skb->data[hard_header_len];
// set protocol default value
skb->protocol = htons(ETH_P_IPV6);
// If type Ethernet, correct it
#ifdef NAS_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, gdev);
#endif
break;
case 4:
#ifdef NAS_DEBUG_RECEIVE_BASIC
printk("nasmt_COMMON_receive: receive IPv4 message\n");
#endif
#ifdef NAS_DEBUG_RECEIVE
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr;
if (addr) {
printk("nasmt_COMMON_receive: Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr;
if (addr) {
printk("[NAS][COMMON][RECEIVE] Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
printk("[NAS][COMMON][RECEIVE] protocol %d\n",((struct iphdr *)&skb->data[hard_header_len])->protocol);
#endif
skb->network_header = &skb->data[hard_header_len];
// set protocol default value
skb->protocol = htons(ETH_P_IP);
// If type Ethernet, correct it
#ifdef NAS_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, gdev);
#endif
break;
default:
printk("nasmt_COMMON_receive: Packet is not IPv4 or IPv6 (version=%d)\n", ipv->version);
#ifdef NAS_DRIVER_TYPE_ETHERNET
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: ether_type=%04X\n", ether_type);
#endif
skb->protocol = eth_type_trans(skb, gdev);
// minus 1(short) instead of 2(bytes) because uint16_t*
p_ether_type = (uint16_t *)&(skb->mac_header[hard_header_len-2]);
ether_type = ntohs(*p_ether_type);
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: ether_type=%04X\n", ether_type);
#endif
switch (ether_type) {
case ETH_P_ARP:
printk("[NAS][COMMON] ether_type = ETH_P_ARP\n");
skb->protocol = htons(ETH_P_ARP);
skb->network_header = &skb->mac_header[hard_header_len];
break;
default:
break;
}
#endif
}
++gpriv->stats.rx_packets;
gpriv->stats.rx_bytes += bytes_read;
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: forwarding packet of size %d to kernel\n",skb->len);
#endif
netif_rx(skb);
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_receive: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete the data
void nasmt_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp)
{
//---------------------------------------------------------------------------
#ifdef NAS_DEBUG_SEND
printk("nasmt_COMMON_del_send - updating statistics \n");
#endif
++gpriv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
//struct pdcp_data_req pdcph;
struct pdcp_data_req_header_t pdcph;
int bytes_wrote = 0;
// Start debug information
#ifdef NAS_DEBUG_SEND
printk("nasmt_COMMON_QOS_send - begin \n");
#endif
// if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
// {
// gpriv->stats.tx_dropped ++;
// printk("NAS_QOS_SEND: No connected, so message are dropped \n");
// return;
// }
if (!skb || !gc || !cx) {
printk("nasmt_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n");
return;
}
// End debug information
if (gc->rb==NULL) {
gc->rb = nasmt_COMMON_search_rb(cx, gc->rab_id);
if (gc->rb==NULL) {
++gpriv->stats.tx_dropped;
printk("nasmt_COMMON_QOS_send: No corresponding Radio Bearer, so message is dropped, rab_id=%u \n", gc->rab_id);
return;
}
}
#ifdef NAS_DEBUG_SEND
printk("nasmt_COMMON_QOS_send #1 :");
printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id);
nasmt_TOOL_print_classifier(gc);
#endif
pdcph.data_size = skb->len;
pdcph.rb_id = ((gc->rb)->rab_id+(32*cx->lcr))-NAS_SIG_NUM_SRB;
pdcph.inst = 0;
#ifdef PDCP_USE_NETLINK
bytes_wrote = nasmt_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP);
//printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len);
#else
//bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE);
bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE);
//printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len);
#endif //PDCP_USE_NETLINK
if (bytes_wrote != NAS_PDCPH_SIZE) {
printk("nasmt_COMMON_QOS_send: problem while writing PDCP's header\n");
printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef PDCP_USE_NETLINK
bytes_wrote += nasmt_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP);
#else
//bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len);
bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len);
#endif //PDCP_USE_NETLINK
if (bytes_wrote != skb->len + NAS_PDCPH_SIZE) {
printk("nasmt_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion
printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef NAS_DEBUG_SEND
printk("nasmt_COMMON_QOS_send - %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id,NAS2PDCP_FIFO);
#endif
gpriv->stats.tx_bytes += skb->len;
gpriv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND
printk("nasmt_COMMON_QOS_send - end \n");
#endif
}
#ifndef PDCP_USE_NETLINK
//---------------------------------------------------------------------------
void nasmt_COMMON_QOS_receive(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
uint8_t sapi;
//struct pdcp_data_ind pdcph;
struct pdcp_data_ind_header_t pdcph;
int bytes_read = 0;
// Start debug information
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_QOS_receive - begin \n");
#endif
if (!cx) {
printk("nasmt_COMMON_QOS_receive - input parameter cx is NULL \n");
return;
}
// End debug information
// LG force the use of only 1 rt fifo
sapi = NAS_DRB_OUTPUT_SAPI;
bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE);
while (bytes_read>0) {
if (bytes_read != NAS_PDCPH_SIZE) {
printk("nasmt_COMMON_QOS_receive: problem while reading PDCP header\n");
return;
}
//void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
// data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer)
nasmt_COMMON_receive(NAS_PDCPH_SIZE, pdcph.data_size, NULL, pdcph->rb_id, gpriv->sap[sapi]);
// check if another frame is in the FIFO, otherwise return
bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE);
}
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_QOS_receive - end \n");
#endif
}
#else
//---------------------------------------------------------------------------
void nasmt_COMMON_QOS_receive(struct nlmsghdr *nlh)
{
//---------------------------------------------------------------------------
struct pdcp_data_ind_header_t *pdcph;
// Start debug information
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_QOS_receive - begin \n");
#endif
if (!nlh) {
printk("nasmt_COMMON_QOS_receive - input parameter nlh is NULL \n");
return;
}
// End debug information
pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh);
#ifdef NAS_DEBUG_RECEIVE
printk("nasmt_COMMON_QOS_receive - receive from PDCP, size %d, rab %d\\n", pdcph->data_size, pdcph->rb_id);
#endif //NAS_DEBUG_RECEIVE
//void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
nasmt_COMMON_receive(NAS_PDCPH_SIZE + pdcph->data_size, pdcph->data_size, (unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE, pdcph->rb_id, 0);
}
#endif //PDCP_USE_NETLINK
//---------------------------------------------------------------------------
struct cx_entity *nasmt_COMMON_search_cx(nasLocalConnectionRef_t lcr)
{
//---------------------------------------------------------------------------
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_search_cx - lcr %d\n",lcr);
#endif
if (lcr<NAS_CX_MAX)
return gpriv->cx+lcr;
else
return NULL;
}
//---------------------------------------------------------------------------
// Search a Radio Bearer
struct rb_entity *nasmt_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_search_rb - rab_id %d\n", rab_id);
#endif
if (!cx) {
printk("nasmt_COMMON_search_rb - input parameter cx is NULL \n");
return NULL;
}
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
if (rb->rab_id==rab_id)
return rb;
}
return NULL;
}
//---------------------------------------------------------------------------
struct rb_entity *nasmt_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_add_rb - begin for rab_id %d , qos %d\n", rab_id, qos );
#endif
if (cx==NULL) {
printk("nasmt_COMMON_add_rb - input parameter cx is NULL \n");
return NULL;
}
rb=nasmt_COMMON_search_rb(cx, rab_id);
if (rb==NULL) {
rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL);
if (rb!=NULL) {
rb->retry=0;
rb->countimer=NAS_TIMER_IDLE;
rb->rab_id=rab_id;
// rb->rab_id=rab_id+(32*cx->lcr);
#ifdef NAS_DEBUG_DC
printk("nasmt_COMMON_add_rb: rb rab_id=%u, rab_id=%u, mt_id=%u\n",rb->rab_id,rab_id, cx->lcr);
#endif
rb->qos=qos;
rb->sapi=NAS_DRB_INPUT_SAPI;
// LG force the use of only one rt-fifo rb->sapi=NAS_BA_INPUT_SAPI;
rb->state=NAS_IDLE;
rb->next=cx->rb;
cx->rb=rb;
++cx->num_rb;
} else
printk("nasmt_COMMON_add_rb: no memory\n");
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_add_rb - end \n" );
#endif
return rb;
}
//---------------------------------------------------------------------------
// free the memory that has previously been allocated to rb and remove from linked list
void nasmt_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp)
{
//---------------------------------------------------------------------------
struct rb_entity *rb, *curr_rb, *prev_rb;
struct classifier_entity *p;
uint16_t classref=0;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_del_rb - begin\n");
#endif
if (cx==NULL) {
printk("nasmt_COMMON_del_rb - input parameter cx is NULL \n");
return;
}
// End debug information
// Clear the associated classifier
for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) {
if (p->classref>=classref) {
classref=p->classref;
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_del_rb: classifier found for dscp %u \n", dscp);
#endif
}
}
nasmt_CLASS_del_sclassifier(cx, dscp, classref);
// Now, delete the RB
curr_rb = NULL;
prev_rb = NULL;
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
if (rb->rab_id == rab_id) {
curr_rb = rb;
if (prev_rb!=NULL) {
prev_rb->next = rb->next;
} else {
cx->rb=rb->next;
}
break;
} else {
prev_rb = rb;
}
}
if (curr_rb!= NULL) {
printk("nasmt_COMMON_del_rb: del rab_id %u\n", rb->rab_id);
kfree(rb);
(cx->num_rb)--;
} else {
printk("\n\n--nasmt_COMMON_del_rb: ERROR, invalid rab_id %u\n", rb->rab_id);
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_del_rb - end\n");
#endif
}
//---------------------------------------------------------------------------
void nasmt_COMMON_flush_rb(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
struct classifier_entity *gc;
uint8_t dscp;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_flush_rb - begin\n");
#endif
if (cx==NULL) {
printk("nasmt_COMMON_flush_rb - input parameter cx is NULL \n");
return;
}
// End debug information
for (rb=cx->rb; rb!=NULL; rb=cx->rb) {
printk("nasmt_COMMON_flush_rb: del rab_id %u\n", rb->rab_id);
cx->rb=rb->next;
kfree(rb);
}
cx->num_rb=0;
cx->rb=NULL;
for(dscp=0; dscp<NAS_DSCP_MAX; ++dscp) {
for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next)
gc->rb=NULL;
}
#ifdef NAS_DEBUG_CLASS
printk("nasmt_COMMON_flush_rb - end\n");
#endif
}
@@ -1,210 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_constant.h
* \brief Defines all constants for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASMTD_CST
#define _NASMTD_CST
//Debug flags
#define NAS_DEBUG_DC
//#define NAS_DEBUG_DC_DETAIL // detail of DC-SAP operation
#define NAS_DEBUG_SEND
#define NAS_DEBUG_SEND_DETAIL // detail of packet transmission
//#define NAS_DEBUG_RECEIVE
#define NAS_DEBUG_RECEIVE_BASIC
#define NAS_DEBUG_CLASS
//#define NAS_DEBUG_GC
//#define NAS_DEBUG_DC_MEASURE
//#define NAS_DEBUG_TIMER
#define NAS_DEBUG_DEVICE
//#define NAS_DEBUG_INTERRUPT
//#define NAS_DEBUG_TOOL
#define NETLINK_DEBUG
//#define NAS_DEBUG_RRCNL // RRC netlink socket
// Other flags
#define DEMO_3GSM
#define ENABLE_SLEEP_MODE
// Parameters for the default RAB started after attachment (needs DEMO_3GSM defined)
#define NASMT_DEFAULTRAB_CLASSREF 1 //MW-01/01/07-
#define NASMT_DEFAULTRAB_DSCP 0 //MW-01/01/07-
#define NASMT_DEFAULTRAB_IPVERSION NAS_VERSION_DEFAULT //MW-01/01/07-
#define NAS_DEFAULT_IPv6_PREFIX_LENGTH 128 // used to compare destination address
// General Constants
#define NAS_MTU 1500
#define NAS_TX_QUEUE_LEN 100
#define NAS_ADDR_LEN 8
#define NAS_INET6_ADDRSTRLEN 46
#define NAS_INET_ADDRSTRLEN 16
#define NAS_RESET_RX_FLAGS 0
#define NAS_CX_MAX 1
//#define NAS_CX_MULTICAST_ALLNODE 2
#define NASMT_MBMS_SVCES_MAX 4 // Identical to RRC constant
#define NAS_RETRY_LIMIT_DEFAULT 5
#define NAS_MESSAGE_MAXLEN 1600
// UMTS
#define NAS_SIG_SRB3 3
#define NAS_SIG_SRB4 3 // not used yet
//LTE
#define NAS_SIG_NUM_SRB 3 // number of srbs in LTE to send Rb_Id to PDCP
//peer-to-peer messages between NAS entities
#define NAS_CMD_OPEN_RB 1
#define NAS_CMD_ENTER_SLEEP 2
#define NAS_CMD_LEAVE_SLEEP 3
//#define NAS_IID1_CONTROL 0x0
//#define NAS_IID2_CONTROL __constant_htonl(0xffffffff)
//#define NAS_STATE_IDLE 0
//#define NAS_STATE_CONNECTED 1
//#define NAS_STATE_ESTABLISHMENT_REQUEST 2
//#define NAS_STATE_ESTABLISHMENT_FAILURE 3
//#define NAS_STATE_RELEASE_FAILURE 4
#define NAS_CX_RELEASE_UNDEF_CAUSE 1
// MT+RG NAS States
#define NAS_IDLE 0x01
// Connection
#define NAS_CX_FACH 0x06
#define NAS_CX_DCH 0x0A
#define NAS_CX_RECEIVED 0x10
#define NAS_CX_CONNECTING 0x04
#define NAS_CX_RELEASING 0x08
#define NAS_CX_CONNECTING_FAILURE 0x14
#define NAS_CX_RELEASING_FAILURE 0x18
// Radio Bearers
#define NAS_RB_ESTABLISHING 0x24
#define NAS_RB_RELEASING 0x28
#define NAS_RB_DCH 0x2A
#define NAS_TIMER_ESTABLISHMENT_DEFAULT 12
#define NAS_TIMER_RELEASE_DEFAULT 2
#define NAS_TIMER_IDLE UINT_MAX
#define NAS_TIMER_TICK HZ
#define NAS_PDCPH_SIZE sizeof(struct pdcp_data_req_header_t)
#define NAS_IPV4_SIZE 20
#define NAS_IPV6_SIZE 40
#define NAS_DIRECTION_SEND 0
#define NAS_DIRECTION_RECEIVE 1
// function number
#define NAS_FCT_DEL_SEND 1
#define NAS_FCT_QOS_SEND 2
#define NAS_FCT_DC_SEND 3
#define NAS_FCT_CTL_SEND 4
// type of IOCTL command
#define NASMT_IOCTL_RAL 0x89F0
// Error cause
#define NAS_ERROR_ALREADYEXIST 1
#define NAS_ERROR_NOMEMORY 3
#define NAS_ERROR_NOTMT 9
#define NAS_ERROR_NOTRG 10
#define NAS_ERROR_NOTIDLE 11
#define NAS_ERROR_NOTCONNECTED 12
#define NAS_ERROR_NORB 14
#define NAS_ERROR_NOTCORRECTVALUE 32
#define NAS_ERROR_NOTCORRECTLCR 33
#define NAS_ERROR_NOTCORRECTDIR 34
#define NAS_ERROR_NOTCORRECTDSCP 35
#define NAS_ERROR_NOTCORRECTVERSION 36
#define NAS_ERROR_NOTCORRECTRABI 37
/**********************************************************/
/* Constants related with IP protocols */
/**********************************************************/
// Destination address types
#define NAS_IPV6_ADDR_UNICAST 1
#define NAS_IPV6_ADDR_MC_SIGNALLING 2
#define NAS_IPV6_ADDR_MC_MBMS 3
#define NAS_IPV6_ADDR_UNKNOWN 4
#define NAS_IPV4_ADDR_UNICAST 5
#define NAS_IPV4_ADDR_MC_SIGNALLING 6
#define NAS_IPV4_ADDR_BROADCAST 7
#define NAS_IPV4_ADDR_UNKNOWN 8
//#define NAS_PORT_CONTROL __constant_htons(0xc45)
//#define NAS_PORT_AUTHENTICATION __constant_htons(1811)
//#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000) //Yan
#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0ff00000)
// Network control codepoint 111000 + IP version 6
#define NAS_FLOWINFO_NCONTROL __constant_htonl(0x6e000000)
// network control codepoint 111000
#define NAS_DSCP_NCONTROL 56 //0x38
// default codepoint 1000000
#define NAS_DSCP_DEFAULT 64
#define NAS_DSCP_MAX 65
#define NAS_PROTOCOL_DEFAULT 0
#define NAS_PROTOCOL_TCP IPPROTO_TCP
#define NAS_PROTOCOL_UDP IPPROTO_UDP
#define NAS_PROTOCOL_ICMP4 IPPROTO_ICMP
#define NAS_PROTOCOL_ICMP6 IPPROTO_ICMPV6
#define NAS_PORT_DEFAULT __constant_htons(65535)
#define NAS_PORT_HTTP __constant_htons(80)
#define NAS_VERSION_DEFAULT 0
#define NAS_VERSION_4 4
#define NAS_VERSION_6 6 //?MW
/**********************************************************/
/* Constants related with Netlink sockets */
/**********************************************************/
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
// defined in rrc_nas_sap.h
//#define NAS_RRCNL_ID 30
//#define NL_DEST_RRC_PID 2
#define NASNL_DEST_PDCP 0
#define NASNL_DEST_RRC 1
#endif
@@ -1,565 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_device.c
* \brief Networking Device Driver for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef PDCP_USE_NETLINK
#ifdef RTAI
#include "rtai_posix.h"
#define RTAI_IRQ 30 //try to get this irq with RTAI
#endif // RTAI
#endif // PDCP_USE_NETLINK
//:::::::::::::::::::::::::::::::::::::::;;
#include "nasmt_variables.h"
#include "nasmt_proto.h"
//:::::::::::::::::::::::::::::::::::::::;;
//#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/if_ether.h>
#endif
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <asm/unistd.h>
#include <linux/netdevice.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
//:::::::::::::::::::::::::::::::::::::::;;
struct net_device *gdev;
struct nas_priv *gpriv;
//int bytes_wrote;
//int bytes_read;
uint8_t NAS_NULL_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00};
uint8_t NAS_RG_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x01};
// TEMP
//uint8_t nas_IMEI[14];
static unsigned char nas_IMEI[14];
static int m_arg=0;
#ifdef PDCP_USE_NETLINK
extern void nasmt_netlink_release(void);
extern int nasmt_netlink_init(void);
#endif
extern void nasmt_ASCTL_timer(unsigned long data);
#ifndef PDCP_USE_NETLINK
//---------------------------------------------------------------------------
//void nasmt_interrupt(void){
void *nasmt_interrupt(void)
{
//---------------------------------------------------------------------------
uint8_t cxi;
char *buffer = NULL;
#ifdef NAS_DEBUG_INTERRUPT
printk("nasmt_interrupt - begin\n");
#endif
//spin_lock(&gpriv->lock);
cxi=0;
nasmt_COMMON_QOS_receive(gpriv->cx+cxi);
nasmt_ASCTL_GC_receive(buffer);
nasmt_ASCTL_DC_receive(gpriv->cx+cxi, buffer);
//spin_unlock(&gpriv->lock);
#ifdef NAS_DEBUG_INTERRUPT
printk("nasmt_interrupt: end\n");
#endif
}
#endif //NETLINK
//---------------------------------------------------------------------------
// Called by ifconfig when the device is activated by ifconfig
int nasmt_open(struct net_device *dev)
{
//---------------------------------------------------------------------------
printk("nasmt_open: begin\n");
gpriv=netdev_priv(dev);
// Address has already been set at init
#ifndef PDCP_USE_NETLINK
if (gpriv->irq==-EBUSY) {
printk("nasmt_open: irq failure\n");
return -EBUSY;
}
#endif //NETLINK
// next lines prevent compilation of the driver with kernel version under 2.6.29
// ATTENTION !!!!!! NASMT is not usable with these versions
if(!netif_queue_stopped(dev))
netif_start_queue(dev);
else
netif_wake_queue(dev);
//
init_timer(&gpriv->timer);
(gpriv->timer).expires=jiffies+NAS_TIMER_TICK;
(gpriv->timer).data=0L;
(gpriv->timer).function=nasmt_ASCTL_timer;
// ??LITE comments: add_timer(&gpriv->timer);
add_timer(&gpriv->timer);
//
printk("nasmt_open: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is desactivated by ifconfig
int nasmt_stop(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct nas_priv *priv = netdev_priv(dev);
printk("nasmt_stop: begin\n");
del_timer(&priv->timer);
netif_stop_queue(dev);
printk("nasmt_stop: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
void nasmt_teardown(struct net_device *dev)
{
//---------------------------------------------------------------------------
int cxi;
#ifndef PDCP_USE_NETLINK
struct nas_priv *priv = netdev_priv(dev);
#endif //PDCP_USE_NETLINK
printk("nasmt_teardown: begin\n");
// priv=(struct nas_priv *)(gdev.priv);
if (dev) {
#ifndef PDCP_USE_NETLINK
if (priv->irq!=-EBUSY) {
*pt_nas_ue_irq=-1;
rt_free_srq(priv->irq);
}
#endif //PDCP_USE_NETLINK
#ifdef PDCP_USE_NETLINK
nasmt_netlink_release();
#endif //PDCP_USE_NETLINK
// for (sapi=0; sapi<NAS_SAPI_MAX; ++sapi)
// close(priv->sap[sapi]);
nasmt_CLASS_flush_rclassifier();
cxi=0;
nasmt_COMMON_flush_rb(gpriv->cx+cxi);
nasmt_CLASS_flush_sclassifier(gpriv->cx+cxi);
// for (sapi=0; sapi<NAS_SAPI_CX_MAX; ++sapi)
// close(priv->cx[cxi].sap[sapi]);
} // check dev
else {
printk("nasmt_teardown: Device is null\n");
}
printk("nasmt_teardown: end\n");
}
//---------------------------------------------------------------------------
int nasmt_set_config(struct net_device *dev, struct ifmap *map)
{
//---------------------------------------------------------------------------
printk("nasmt_set_config: begin\n");
if (dev->flags & IFF_UP)
return -EBUSY;
if (map->base_addr != dev->base_addr) {
printk(KERN_WARNING "nasmt_set_config: Can't change I/O address\n");
return -EOPNOTSUPP;
}
if (map->irq != dev->irq)
dev->irq = map->irq;
printk("nasmt_set_config: end\n");
return 0;
}
//---------------------------------------------------------------------------
//
int nasmt_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_DEVICE
printk("nasmt_hard_start_xmit: begin\n");
#endif
if ((!skb)||(!dev)) {
printk("nasmt_hard_start_xmit - input parameter skb or dev is NULL \n");
return -1;
}
// End debug information
netif_stop_queue(dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasmt_hard_start_xmit: step 1\n");
#endif
nasmt_CLASS_send(skb);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasmt_hard_start_xmit: step 2\n");
#endif
dev_kfree_skb(skb);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasmt_hard_start_xmit: step 3\n");
#endif
netif_wake_queue(dev);
#ifdef NAS_DEBUG_DEVICE
printk("nasmt_hard_start_xmit: end\n");
#endif
return 0;
}
//---------------------------------------------------------------------------
struct net_device_stats *nasmt_get_stats(struct net_device *dev)
{
//---------------------------------------------------------------------------
// return &((struct nas_priv *)dev->priv)->stats;
struct nas_priv *npriv = netdev_priv(dev);
return &npriv->stats;
}
//---------------------------------------------------------------------------
// New function from LITE DRIVER
int nasmt_set_mac_address(struct net_device *dev, void *mac)
{
//---------------------------------------------------------------------------
struct sockaddr *addr = mac;
printk("nasmt_set_mac_address: begin\n");
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
return 0;
}
//---------------------------------------------------------------------------
int nasmt_change_mtu(struct net_device *dev, int mtu)
{
//---------------------------------------------------------------------------
printk("nasmt_change_mtu: begin\n");
if ((mtu<50) || (mtu>1500))
// if ((mtu<1280) || (mtu>1500))
return -EINVAL;
dev->mtu = mtu;
return 0;
}
//---------------------------------------------------------------------------
int nasmt_change_rx_flags(struct net_device *dev, int flags)
{
//---------------------------------------------------------------------------
//struct nas_priv *priv = netdev_priv(dev);
printk("nasmt_change_rx_flags %08X\n", flags);
gpriv->rx_flags ^= flags;
return 0;
}
//---------------------------------------------------------------------------
void nasmt_tx_timeout(struct net_device *dev)
{
//---------------------------------------------------------------------------
/* Transmitter timeout, serious problems. */
printk("nasmt_tx_timeout: begin\n");
//((struct nas_priv *)(dev->priv))->stats.tx_errors++;
(gpriv->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
netif_wake_queue(dev);
printk("nasmt_tx_timeout: transmit timed out %s\n",dev->name);
}
//---------------------------------------------------------------------------
// Define pointers for the module
static const struct net_device_ops nasmt_netdev_ops = {
// ?? nasmt_interrupt
//
.ndo_open = nasmt_open,
.ndo_stop = nasmt_stop,
.ndo_start_xmit = nasmt_hard_start_xmit,
.ndo_validate_addr = NULL,
.ndo_get_stats = nasmt_get_stats,
//#ifdef KERNEL_VERSION_GREATER_THAN_32
// .ndo_set_multicast_list = NULL,
.ndo_set_mac_address = nasmt_set_mac_address,
.ndo_set_config = nasmt_set_config,
.ndo_do_ioctl = nasmt_CTL_ioctl,
.ndo_change_mtu = nasmt_change_mtu,
.ndo_tx_timeout = nasmt_tx_timeout,
.ndo_change_rx_flags = nasmt_change_rx_flags,
//#endif
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Initialisation of the network device
void nasmt_init(struct net_device *dev)
{
//---------------------------------------------------------------------------
uint8_t cxi, dscpi;
printk("nasmt_init: begin\n");
if (dev) {
gpriv=netdev_priv(dev);
memset(gpriv, 0, sizeof(struct nas_priv));
// Initialize function pointers
dev->netdev_ops = &nasmt_netdev_ops;
#ifndef NAS_DRIVER_TYPE_ETHERNET
// Update driver properties
dev->type = ARPHRD_EURUMTS;
dev->features = NETIF_F_NO_CSUM;
dev->hard_header_len = 0;
dev->addr_len = NAS_ADDR_LEN;
dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
dev->tx_queue_len = NAS_TX_QUEUE_LEN;
dev->mtu = NAS_MTU;
#endif
// Can be one of the following enum defined in include/linux/netdevice.h:
// enum netdev_state_t {
// __LINK_STATE_START,
// __LINK_STATE_PRESENT,
// __LINK_STATE_NOCARRIER,
// __LINK_STATE_LINKWATCH_PENDING,
// __LINK_STATE_DORMANT,
// };
set_bit(__LINK_STATE_PRESENT, &dev->state);
#ifdef NAS_DRIVER_TYPE_ETHERNET
// overwrite values written above ( header_ops,type,hard_header_len,mtu,addr_len,tx_queue_len,flags,broadcast)
printk("\nnasmt_init: WARNING Driver type ETHERNET\n");
ether_setup(dev);
#endif
//
// Initialize private structure
gpriv->rx_flags = NAS_RESET_RX_FLAGS;
gpriv->sap[NAS_GC_SAPI] = RRC_DEVICE_GC;
gpriv->sap[NAS_NT_SAPI] = RRC_DEVICE_NT;
gpriv->cx[0].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0;
gpriv->cx[0].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0;
//gpriv->sap[NAS_CO_INPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_INPUT;
//gpriv->sap[NAS_CO_OUTPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_OUTPUT;
gpriv->sap[NAS_DRB_INPUT_SAPI] = PDCP2PDCP_USE_RT_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT;
gpriv->sap[NAS_DRB_OUTPUT_SAPI] = NAS2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT;
gpriv->retry_limit = NAS_RETRY_LIMIT_DEFAULT;
gpriv->timer_establishment = NAS_TIMER_ESTABLISHMENT_DEFAULT;
gpriv->timer_release = NAS_TIMER_RELEASE_DEFAULT;
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi)
gpriv->rclassifier[dscpi] = NULL;
gpriv->nrclassifier = 0;
//
cxi=0;
#ifdef NAS_DEBUG_DEVICE
printk("nasmt_init: init classifiers, state and timer for MT %u\n", cxi);
#endif
gpriv->cx[cxi].state = NAS_IDLE;
gpriv->cx[cxi].countimer = NAS_TIMER_IDLE;
gpriv->cx[cxi].retry = 0;
gpriv->cx[cxi].lcr = cxi;
gpriv->cx[cxi].rb = NULL;
gpriv->cx[cxi].num_rb = 0;
// initialisation of the classifiers
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi) {
gpriv->cx[cxi].sclassifier[dscpi]=NULL;
}
gpriv->cx[cxi].nsclassifier=0;
// initialisation of the IP address
nasmt_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)gpriv->cx[cxi].iid6);
gpriv->cx[cxi].iid4=0;
//
spin_lock_init(&gpriv->lock);
printk("nasmt_init: init IMEI to IID\n");
#ifdef NAS_DRIVER_TYPE_ETHERNET
nasmt_TOOL_eth_imei2iid(nas_IMEI, dev->dev_addr ,(uint8_t *)gpriv->cx[0].iid6, dev->addr_len);
#else
nasmt_TOOL_imei2iid(nas_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address)
nasmt_TOOL_imei2iid(nas_IMEI, (uint8_t *)gpriv->cx[0].iid6);
#endif
nasmt_ASCTL_init();
} else {
printk("\n\nnasmt_init: ERROR, Device is NULL!!\n");
}
printk("nasmt_init: end\n");
return;
}
//---------------------------------------------------------------------------
int init_module (void)
{
//---------------------------------------------------------------------------
int err;
int inst = 0;
int index;
struct nas_priv *priv;
char devicename[100];
printk("\n\n\ninit_module: begin \n");
// check IMEI parameter
printk("number of IMEI parameters %d, IMEI ", m_arg);
for (index = 0; index < m_arg; index++) {
printk("%02X ", nas_IMEI[index]);
}
printk("\n");
#ifndef PDCP_USE_NETLINK
// Initialize parameters shared with RRC (done first to avoid going further)
if (pt_nas_ue_irq==NULL) {
printk("init_module: shared irq parameter not initialised\n");
err = -EBUSY;
printk("init_module: returning %d \n\n", err);
return err;
}
printk("init_module: pt_nas_ue_irq valid \n");
#endif
// Allocate device structure
sprintf(devicename,"oai%d",inst);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
gdev = alloc_netdev(sizeof(struct nas_priv), devicename, nasmt_init);
#else
gdev = alloc_netdev(sizeof(struct nas_priv), devicename, NET_NAME_PREDICTABLE, nasmt_init);
#endif
priv = netdev_priv(gdev);
////
#ifndef PDCP_USE_NETLINK
priv->irq=rt_request_srq(0, nasmt_interrupt, NULL);
if (priv->irq == -EBUSY || priv->irq == -EINVAL) {
printk("\n init_module: No interrupt resource available\n");
if (gdev) {
free_netdev(gdev);
printk("init_module: free_netdev ..\n");
}
return -EBUSY;
} else
printk("init_module: Interrupt %d, ret = %d \n", priv->irq , ret);
if (pt_nas_ue_irq==NULL) {
printk("init_module: shared irq parameter has been reset\n");
} else {
*pt_nas_ue_irq=priv->irq;
}
#endif
#ifdef PDCP_USE_NETLINK
if ((err=nasmt_netlink_init()) == -1)
printk("init_module: NETLINK failed\n");
printk("init_module: NETLINK INIT successful\n");
#endif //NETLINK
//
err= register_netdev(gdev);
if (err) {
printk("init_module: error %i registering device %s\n", err, gdev->name);
} else {
printk("init_module: registering device %s, ifindex = %d\n\n",gdev->name, gdev->ifindex);
}
return err;
}
//---------------------------------------------------------------------------
void cleanup_module(void)
{
//---------------------------------------------------------------------------
printk("nasmt_cleanup_module: begin\n");
unregister_netdev(gdev);
nasmt_teardown(gdev);
free_netdev(gdev);
printk("nasmt_cleanup_module: end\n\n\n\n");
}
//---------------------------------------------------------------------------
// Replaced by init_module and cleanup_module
//module_init (nasmt_init_module);
//module_exit (nasmt_cleanup_module);
//---------------------------------------------------------------------------
#define DRV_NAME "oai_nasmt"
#define DRV_VERSION "3.0.1"DRV_NAME
#define DRV_DESCRIPTION "OPENAIR CELLULAR LTE NASMT Device Driver"
#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2013"
#define DRV_AUTHOR "Michelle Wetterwald <michelle.wetterwald@eurecom.fr>"DRV_COPYRIGHT
module_param_array_named(nas_IMEI,nas_IMEI,byte,&m_arg,0);
//module_param_array(oai_nw_drv_IMEI,byte,&m_arg,0444);
MODULE_PARM_DESC(nas_IMEI,"Terminal IMEI Identifier (14 digits, only first 10 significant if ETH option ON)");
// MODULE_LICENSE("GPL");
// MODULE_DESCRIPTION("LTE Driver for Mobile Terminal, playing as Non Access Stratum");
// MODULE_AUTHOR("Michelle Wetterwald <michelle.wetterwald@eurecom.fr>");
@@ -1,764 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_iocontrol.c
* \brief I/O control functions for upper layers of driver for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasmt_variables.h"
#include "nasmt_iocontrol.h"
#include "nasmt_proto.h"
//#include <linux/in.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/uaccess.h>
extern int nasmt_ASCTL_DC_send_cx_establish_request(struct cx_entity *cx);
// Statistic
//---------------------------------------------------------------------------
void nasmt_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep)
{
//---------------------------------------------------------------------------
msgrep->rx_packets=gpriv->stats.rx_packets;
msgrep->tx_packets=gpriv->stats.tx_packets;
msgrep->rx_bytes=gpriv->stats.rx_bytes;
msgrep->tx_bytes=gpriv->stats.tx_bytes;
msgrep->rx_errors=gpriv->stats.rx_errors;
msgrep->tx_errors=gpriv->stats.tx_errors;
msgrep->rx_dropped=gpriv->stats.rx_dropped;
msgrep->tx_dropped=gpriv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_statistic_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_statistic_reply msgrep;
printk("nasmt_ioCTL_statistic: stat requested\n");
nasmt_set_msg_statistic_reply(&msgrep);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_statistic: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connections List
//---------------------------------------------------------------------------
void nasmt_set_msg_cx_list_reply(uint8_t *msgrep)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
nasLocalConnectionRef_t lcr;
struct nas_msg_cx_list_reply *list;
msgrep[0]=NAS_CX_MAX;
list=(struct nas_msg_cx_list_reply *)(msgrep+1);
for(lcr=0; lcr<NAS_CX_MAX; ++lcr) {
cx=nasmt_COMMON_search_cx(lcr);
list[lcr].lcr=lcr;
list[lcr].state=cx->state;
list[lcr].cellid=cx->cellid;
list[lcr].iid4=cx->iid4;
list[lcr].iid6[0]=cx->iid6[0];
list[lcr].iid6[1]=cx->iid6[1];
list[lcr].num_rb=cx->num_rb;
list[lcr].nsclassifier=cx->nsclassifier;
printk("nasmt_set_msg_cx_list_reply: nsc=%u\n",cx->nsclassifier);
}
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_cx_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1];
printk("nasmt_ioCTL_cx_list: connection list requested\n");
nasmt_set_msg_cx_list_reply(msgrep);
if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) {
printk("nasmt_ioCTL_cx_list: copy_to_user failure\n");
return -EFAULT;
}
printk("nasmt_ioCTL_cx_list: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Establishment
//---------------------------------------------------------------------------
void nasmt_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep, struct nas_msg_cx_establishment_request *msgreq)
{
//---------------------------------------------------------------------------
#ifdef NODE_RG
msgrep->status=-NAS_ERROR_NOTMT;
#else
struct cx_entity *cx;
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
if (cx->state == NAS_CX_RELEASING) {
msgrep->status=nasmt_ASCTL_leave_sleep_mode(cx);
} else {
cx->cellid=msgreq->cellid;
msgrep->status=nasmt_ASCTL_DC_send_cx_establish_request(cx);
}
} else
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
#endif
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_cx_establishment_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_establishment_request msgreq;
struct nas_msg_cx_establishment_reply msgrep;
printk("nasmt_ioCTL_cx_establishment: connection establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_cx_establishment: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_cx_establishment_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_cx_establishment: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Release
//---------------------------------------------------------------------------
void nasmt_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep, struct nas_msg_cx_release_request *msgreq)
{
//---------------------------------------------------------------------------
#ifdef NODE_RG
msgrep->status=-NAS_ERROR_NOTMT;
#else
struct cx_entity *cx;
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
#ifdef ENABLE_SLEEP_MODE
msgrep->status=nasmt_ASCTL_enter_sleep_mode(cx);
#endif
#ifndef ENABLE_SLEEP_MODE
msgrep->status=nasmt_ASCTL_DC_send_cx_release_request(cx);
#endif
} else
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
#endif
}
//---------------------------------------------------------------------------
// Request the release of a connection
int nasmt_ioCTL_cx_release_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_release_request msgreq;
struct nas_msg_cx_release_reply msgrep;
printk("nasmt_ioCTL_cx_release: connection release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_cx_release: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_cx_release_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_cx_release: copy_to_user failure\n");
return -EFAULT;
}
printk("nasmt_ioCTL_cx_release: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer List
//---------------------------------------------------------------------------
void nasmt_set_msg_rb_list_reply(uint8_t *msgrep, struct nas_msg_rb_list_request *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
uint8_t rbi;
struct rb_entity *rb;
struct nas_msg_rb_list_reply *list;
if (cx->num_rb > NAS_LIST_RB_MAX)
msgrep[0] = NAS_LIST_RB_MAX;
else
msgrep[0] = cx->num_rb;
list=(struct nas_msg_rb_list_reply *)(msgrep+1);
for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbi<msgrep[0]); rb=rb->next, ++rbi) {
list[rbi].state=rb->state;
list[rbi].rab_id=rb->rab_id;
list[rbi].sapi=rb->sapi;
list[rbi].qos=rb->qos;
}
} else
msgrep[0]=0;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_rb_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1];
struct nas_msg_rb_list_request msgreq;
printk("nasmt_ioCTL_rb_list: Radio Bearer list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_rb_list: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_rb_list_reply(msgrep, &msgreq);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) {
printk("nasmt_ioCTL_rb_list: copy_to_user failure\n");
return -EFAULT;
}
printk("nasmt_ioCTL_rb_list: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Establishment
//---------------------------------------------------------------------------
void nasmt_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep, struct nas_msg_rb_establishment_request *msgreq)
{
//---------------------------------------------------------------------------
msgrep->status=-NAS_ERROR_NOTRG;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_rb_establishment_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_establishment_request msgreq;
struct nas_msg_rb_establishment_reply msgrep;
printk("nasmt_ioCTL_rb_establishment: Radio bearer establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_rb_establishment: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_rb_establishment_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_rb_establishment: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Release
//---------------------------------------------------------------------------
void nasmt_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep, struct nas_msg_rb_release_request *msgreq)
{
//---------------------------------------------------------------------------
msgrep->status=-NAS_ERROR_NOTRG;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_rb_release_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_release_request msgreq;
struct nas_msg_rb_release_reply msgrep;
printk("nasmt_ioCTL_rb_release: Radio bearer release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_rb_release: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_rb_release_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_rb_release: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Classifier List
//---------------------------------------------------------------------------
void nasmt_set_msg_class_list_reply(uint8_t *msgrep, struct nas_msg_class_list_request *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
struct classifier_entity *gc;
struct nas_msg_class_list_reply *list;
uint8_t cli;
list=(struct nas_msg_class_list_reply *)(msgrep+1);
switch(msgreq->dir) {
case NAS_DIRECTION_SEND:
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx==NULL) {
msgrep[0]=0;
return;
}
gc=cx->sclassifier[msgreq->dscp];
break;
case NAS_DIRECTION_RECEIVE:
cx=NULL;
gc=gpriv->rclassifier[msgreq->dscp];
break;
default:
cx=NULL;
msgrep[0]=0;
return;
}
for (cli=0; (gc!=NULL)&&(cli<NAS_LIST_CLASS_MAX); gc=gc->next, ++cli) {
list[cli].classref=gc->classref;
list[cli].lcr=msgreq->lcr;
list[cli].dir=msgreq->dir;
list[cli].dscp=msgreq->dscp;
list[cli].rab_id=gc->rab_id;
list[cli].version=gc->version;
switch(gc->version) {
case 4:
list[cli].saddr.ipv4 = gc->saddr.ipv4;
list[cli].daddr.ipv4 = gc->daddr.ipv4;
break;
case 6:
list[cli].saddr.ipv6 = gc->saddr.ipv6;
list[cli].daddr.ipv6 = gc->daddr.ipv6;
break;
}
list[cli].protocol=gc->protocol;
list[cli].sport=ntohs(gc->sport);
list[cli].dport=ntohs(gc->dport);
list[cli].splen=gc->splen;
list[cli].dplen=gc->dplen;
list[cli].fct=nasmt_TOOL_invfct(gc);
}
msgrep[0]=cli;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_class_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1];
struct nas_msg_class_list_request msgreq;
printk("nasmt_ioCTL_class_list: classifier list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_class_list: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_class_list_reply(msgrep, &msgreq);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) {
printk("nasmt_ioCTL_class_list: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the addition of a classifier rule
//---------------------------------------------------------------------------
void nasmt_set_msg_class_add_reply(struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq)
{
//---------------------------------------------------------------------------
struct classifier_entity *gc;
if (msgreq->dscp>NAS_DSCP_DEFAULT) {
printk("nasmt_set_msg_class_add_reply: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
printk("nasmt_set_msg_class_add_reply: DSCP %d, Classref %d\n",msgreq->dscp, msgreq->classref );
gc=nasmt_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref);
printk("nasmt_set_msg_class_add_reply: %p %p\n" , msgreq, gc);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
gc->rab_id=msgreq->rab_id;
gc->rb=nasmt_COMMON_search_rb(cx, gc->rab_id);
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE) {
gc=nasmt_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
}
nasmt_TOOL_fct(gc, msgreq->fct);
gc->version=msgreq->version;
switch(gc->version) {
case 4:
gc->saddr.ipv4=msgreq->saddr.ipv4;
gc->daddr.ipv4=msgreq->daddr.ipv4;
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case 6:
gc->saddr.ipv6=msgreq->saddr.ipv6;
gc->daddr.ipv6=msgreq->daddr.ipv6;
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case 0:
gc->saddr.ipv6.s6_addr32[0]=0;
gc->daddr.ipv6.s6_addr32[1]=0;
gc->saddr.ipv6.s6_addr32[2]=0;
gc->daddr.ipv6.s6_addr32[3]=0;
gc->splen=0;
gc->dplen=0;
break;
default:
msgrep->status=-NAS_ERROR_NOTCORRECTVERSION;
kfree(gc);
return;
}
gc->protocol=msgreq->protocol;
gc->sport=htons(msgreq->sport);
gc->dport=htons(msgreq->dport);
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_class_add_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_class_add_request msgreq;
struct nas_msg_class_add_reply msgrep;
printk("nasmt_ioCTL_class_add: Add classifier components requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_class_add: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_class_add_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_class_add: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the deletion of a classifier rule
//---------------------------------------------------------------------------
void nasmt_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep, struct nas_msg_class_del_request *msgreq)
{
//---------------------------------------------------------------------------
if (msgreq->dscp>NAS_DSCP_DEFAULT) {
printk("nasmt_set_msg_class_del_reply: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nasmt_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL)
nasmt_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE)
nasmt_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
}
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_class_del_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_class_del_request msgreq;
struct nas_msg_class_del_reply msgrep;
printk("nasmt_ioCTL_class_del: Del classifier components requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_class_del: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_class_del_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_class_del: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Measurement
// Messages for Measurement transfer
//---------------------------------------------------------------------------
void nasmt_set_msg_measure_reply(struct nas_msg_measure_reply *msgrep, struct nas_msg_measure_request *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
int lcr=0; // Temp lcr->mt =0
int i;
cx = nasmt_COMMON_search_cx(lcr);
if (cx!=NULL) {
msgrep->num_cells = cx->num_measures;
for (i=0; i<cx->num_measures; i++) {
msgrep-> measures[i].cell_id = cx->meas_cell_id[i];
msgrep-> measures[i].level = cx->meas_level[i];
msgrep-> measures[i].provider_id = cx->provider_id[i];
}
msgrep->signal_lost_flag = 0;
} else {
// msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
// return;
}
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_measure_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_measure_request msgreq;
struct nas_msg_measure_reply msgrep;
printk("nasmt_ioCTL_measure: Measurement requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasmt_ioCTL_measure: copy_from_user failure\n");
return -EFAULT;
}
nasmt_set_msg_measure_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_measure: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// IMEI
// Messages for IMEI transfer
//---------------------------------------------------------------------------
void nasmt_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
int lcr=0; // Temp lcr->mt =0
int i;
cx=nasmt_COMMON_search_cx(lcr);
if (cx!=NULL) {
msgrep->l2id[0] = cx->iid6[0];
msgrep->l2id[1] = cx->iid6[1];
} else {
// msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
// return;
}
}
//---------------------------------------------------------------------------
int nasmt_ioCTL_imei_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_l2id_reply msgrep;
printk("nasmt_ioCTL_imei: IMEI requested\n");
nasmt_set_msg_imei_reply(&msgrep);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasmt_ioCTL_imei: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IOCTL command
//---------------------------------------------------------------------------
int nasmt_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
//---------------------------------------------------------------------------
struct nas_ioctl *gifr;
int r;
printk("nasmt_CTL_ioctl: begin\n");
//spin_lock(&gpriv->lock);
switch(cmd) {
case NASMT_IOCTL_RAL:
gifr=(struct nas_ioctl *)ifr;
switch(gifr->type) {
case NAS_MSG_STATISTIC_REQUEST:
r=nasmt_ioCTL_statistic_request(gifr);
break;
case NAS_MSG_CX_ESTABLISHMENT_REQUEST:
r=nasmt_ioCTL_cx_establishment_request(gifr);
break;
case NAS_MSG_CX_RELEASE_REQUEST:
r=nasmt_ioCTL_cx_release_request(gifr);
break;
case NAS_MSG_CX_LIST_REQUEST:
r=nasmt_ioCTL_cx_list_request(gifr);
break;
case NAS_MSG_RB_ESTABLISHMENT_REQUEST:
r=nasmt_ioCTL_rb_establishment_request(gifr);
break;
case NAS_MSG_RB_RELEASE_REQUEST:
r= nasmt_ioCTL_rb_release_request(gifr);
break;
case NAS_MSG_RB_LIST_REQUEST:
r=nasmt_ioCTL_rb_list_request(gifr);
break;
case NAS_MSG_CLASS_ADD_REQUEST:
r=nasmt_ioCTL_class_add_request(gifr);
break;
case NAS_MSG_CLASS_LIST_REQUEST:
r=nasmt_ioCTL_class_list_request(gifr);
break;
case NAS_MSG_CLASS_DEL_REQUEST:
r=nasmt_ioCTL_class_del_request(gifr);
break;
case NAS_MSG_MEAS_REQUEST:
r=nasmt_ioCTL_measure_request(gifr);
break;
case NAS_MSG_IMEI_REQUEST:
r=nasmt_ioCTL_imei_request(gifr);
break;
default:
printk("nasmt_CTL_ioctl: unkwon request type, type=%x\n", gifr->type);
r=-EFAULT;
}
break;
default:
printk("nasmt_CTL_ioctl: Unknown ioctl command, cmd=%x\n", cmd);
r=-EFAULT;
}
//spin_unlock(&gpriv->lock);
printk("nasmt_CTL_ioctl: end\n");
return r;
}
//---------------------------------------------------------------------------
void nasmt_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
printk("nasmt_CTL_send - void \n");
}
@@ -1,211 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_iocontrol.h
* \brief I/O control constnats and structures for upper layers of driver for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef NASMTD_CTL_H
#define NASMTD_CTL_H
#include <asm/byteorder.h>
#include <asm/types.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#define NAS_MSG_MAXLEN 1100
// type of CTL message
#define NAS_MSG_STATISTIC_REQUEST 1
#define NAS_MSG_STATISTIC_REPLY 2
#define NAS_MSG_ECHO_REQUEST 3
#define NAS_MSG_ECHO_REPLY 4
#define NAS_MSG_CX_ESTABLISHMENT_REQUEST 5
#define NAS_MSG_CX_ESTABLISHMENT_REPLY 6
#define NAS_MSG_CX_RELEASE_REQUEST 7
#define NAS_MSG_CX_RELEASE_REPLY 8
#define NAS_MSG_CX_LIST_REQUEST 9
#define NAS_MSG_CX_LIST_REPLY 10
#define NAS_MSG_RB_ESTABLISHMENT_REQUEST 11
#define NAS_MSG_RB_ESTABLISHMENT_REPLY 12
#define NAS_MSG_RB_RELEASE_REQUEST 13
#define NAS_MSG_RB_RELEASE_REPLY 14
#define NAS_MSG_RB_LIST_REQUEST 15
#define NAS_MSG_RB_LIST_REPLY 16
#define NAS_MSG_CLASS_ADD_REQUEST 17
#define NAS_MSG_CLASS_ADD_REPLY 18
#define NAS_MSG_CLASS_DEL_REQUEST 19
#define NAS_MSG_CLASS_DEL_REPLY 20
#define NAS_MSG_CLASS_LIST_REQUEST 21
#define NAS_MSG_CLASS_LIST_REPLY 22
#define NAS_MSG_MEAS_REQUEST 23
#define NAS_MSG_MEAS_REPLY 24
#define NAS_MSG_IMEI_REQUEST 25
#define NAS_MSG_IMEI_REPLY 26
// Max number of entry of a message list
#define NAS_LIST_CX_MAX 32
#define NAS_LIST_RB_MAX 32
#define NAS_LIST_CLASS_MAX 32
typedef uint16_t nasMsgType_t;
struct nas_ioctl {
char name[IFNAMSIZ];
nasMsgType_t type;
char *msg;
};
struct nas_msg_statistic_reply {
uint32_t rx_packets;
uint32_t tx_packets;
uint32_t rx_bytes;
uint32_t tx_bytes;
uint32_t rx_errors;
uint32_t tx_errors;
uint32_t rx_dropped;
uint32_t tx_dropped;
};
struct nas_msg_cx_list_reply {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t state;
nasCellID_t cellid; // cell identification
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
uint16_t num_rb;
uint16_t nsclassifier;
};
struct nas_msg_cx_establishment_reply {
int status;
};
struct nas_msg_cx_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasCellID_t cellid; // Cell identification
};
struct nas_msg_cx_release_reply {
int status;
};
struct nas_msg_cx_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
struct nas_msg_rb_list_reply {
nasRadioBearerId_t rab_id;
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
uint8_t state;
};
struct nas_msg_rb_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
struct nas_msg_rb_establishment_reply {
int status;
};
struct nas_msg_rb_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
nasQoSTrafficClass_t qos;
};
struct nas_msg_rb_release_reply {
int status;
};
struct nas_msg_rb_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
};
struct nas_msg_class_add_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
uint8_t dir; // direction (send or receive)
uint8_t dscp; // codepoint
uint8_t fct;
uint16_t classref;
uint8_t version;
union {
struct in6_addr ipv6;
uint32_t ipv4;
} saddr; // IP source address
uint8_t splen; // prefix length
union {
struct in6_addr ipv6;
uint32_t ipv4;
} daddr; // IP destination address
uint8_t dplen; // prefix length
uint8_t protocol; // high layer protocol type
uint16_t sport; // source port
uint16_t dport; // destination port
};
struct nas_msg_class_add_reply {
int status;
};
struct nas_msg_class_del_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t dir; // direction (send or receive)
uint8_t dscp; // codepoint
uint16_t classref;
};
struct nas_msg_class_del_reply {
int status;
};
#define nas_msg_class_list_reply nas_msg_class_add_request
struct nas_msg_class_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t dir;
uint8_t dscp;
};
// Messages for Measurement transfer - MW 01/04/2005
typedef uint32_t nioctlProviderId_t;
typedef uint16_t nioctlSignalLoss_t;
typedef struct nioctlMeasures {
nasCellID_t cell_id;
nasSigLevel_t level;
nioctlProviderId_t provider_id;
} nioctlMeasures_t;
struct nas_msg_measure_request {
nasNumRGsMeas_t num_cells;
nasCellID_t cellid[MAX_MEASURE_NB]; // Cell identification
uint16_t num_providers;
nioctlProviderId_t provider_id[MAX_MEASURE_NB]; // Provider identification
};
struct nas_msg_measure_reply {
nasNumRGsMeas_t num_cells;
nioctlMeasures_t measures[MAX_MEASURE_NB];
nioctlSignalLoss_t signal_lost_flag;
};
// Messages for L2Id transfer - MW
typedef uint32_t nioctlL2Id_t[2];
struct nas_msg_l2id_reply {
nioctlL2Id_t l2id;
};
#endif
@@ -1,233 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_netlink.c
* \brief Netlink socket functions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
//#include <linux/config.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include "nasmt_variables.h"
#include "nasmt_proto.h"
static struct sock *nas_nl_sk = NULL;
static struct sock *nas_rrcnl_sk = NULL;
//static int exit_netlink_thread=0;
static DEFINE_MUTEX(nasmt_mutex);
// This can also be implemented using thread to get the data from PDCP without blocking.
//---------------------------------------------------------------------------
// Function for transfer with PDCP (from NASLITE)
static void nasmt_nl_data_ready (struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct nlmsghdr *nlh = NULL;
// Start debug information
#ifdef NETLINK_DEBUG
printk("nasmt_nl_data_ready - begin \n");
#endif
if (!skb) {
printk("nasmt_nl_data_ready - input parameter skb is NULL \n");
return;
}
// End debug information
#ifdef NETLINK_DEBUG
printk("nasmt_nl_data_ready - Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
nasmt_COMMON_QOS_receive(nlh);
}
//---------------------------------------------------------------------------
// Function for transfer with RRC
static void nasmt_rrcnl_data_ready (struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct nlmsghdr *nlh = NULL;
char target_sap;
uint8_t cxi = 0;
// Start debug information
#ifdef NAS_DEBUG_RRCNL
printk("nasmt_rrcnl_data_ready - begin \n");
#endif
if (!skb) {
printk("nasmt_rrcnl_data_ready - input parameter skb is NULL \n");
return;
}
// End debug information
nlh = (struct nlmsghdr *)skb->data;
//pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh);
//nasmt_TOOL_print_buffer((char *)NLMSG_DATA(nlh), 48);
target_sap = ((char*)NLMSG_DATA(nlh))[0];
#ifdef NAS_DEBUG_RRCNL
printk("nasmt_rrcnl_data_ready - Received on socket from RRC, SAP %d\n", target_sap);
#endif //NAS_DEBUG_RRCNL
switch (target_sap) {
case RRC_NAS_GC_OUT:
//printk("nasmt_rrcnl_data_ready - Calling nasmt_ASCTL_GC_receive\n");
nasmt_ASCTL_GC_receive(&((char*)NLMSG_DATA(nlh))[1]);
break;
case RRC_NAS_DC0_OUT:
//printk("nasmt_rrcnl_data_ready - Calling nasmt_ASCTL_DC_receive\n");
nasmt_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
break;
default:
printk("nasmt_rrcnl_data_ready - Invalid SAP value received\n");
}
}
//---------------------------------------------------------------------------
int nasmt_netlink_init(void)
{
//---------------------------------------------------------------------------
printk("nasmt_netlink_init - begin \n");
nas_nl_sk = netlink_kernel_create(&init_net,OAI_IP_DRIVER_NETLINK_ID, 0, nasmt_nl_data_ready,
&nasmt_mutex, // NULL
THIS_MODULE);
if (!nas_nl_sk) {
printk("nasmt_netlink_init - netlink_kernel_create failed for PDCP socket\n");
return(-1);
}
nas_rrcnl_sk = netlink_kernel_create(&init_net,NAS_RRCNL_ID, 0, nasmt_rrcnl_data_ready,
&nasmt_mutex, // NULL
THIS_MODULE);
if (!nas_rrcnl_sk) {
printk("nasmt_rrcnl_init - netlink_kernel_create failed for RRC socket\n");
return(-1);
}
return(0);
}
//---------------------------------------------------------------------------
void nasmt_netlink_release(void)
{
//---------------------------------------------------------------------------
printk("nasmt_netlink_release - begin \n");
//exit_netlink_thread=1;
printk("nasmt_netlink_release - Releasing netlink sockets\n");
if(nas_nl_sk) {
netlink_kernel_release(nas_nl_sk);
}
if(nas_rrcnl_sk) {
netlink_kernel_release(nas_rrcnl_sk);
}
}
//---------------------------------------------------------------------------
int nasmt_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination)
{
//---------------------------------------------------------------------------
struct sk_buff *nl_skb;
struct nlmsghdr *nlh;
int status;
// Start debug information
#ifdef NETLINK_DEBUG
printk("nasmt_netlink_send - begin \n");
#endif
if (!data_buffer) {
printk("nasmt_netlink_send - ERROR - input parameter data is NULL \n");
return(0);
}
if (!nas_nl_sk || !nas_rrcnl_sk) {
printk("nasmt_netlink_send - ERROR - socket is NULL\n");
return(0);
}
// End debug information
nl_skb = alloc_skb(NLMSG_SPACE(data_length),GFP_ATOMIC);
if (!nl_skb) {
printk("nasmt_netlink_send - ERROR - could not allocate skbuffer\n");
return(0);
}
nlh = (struct nlmsghdr *)nl_skb->data;
// printk("nasmt_netlink_send Sending %d bytes (%d)\n",data_length,NLMSG_SPACE(data_length));
skb_put(nl_skb, NLMSG_SPACE(data_length));
memcpy(NLMSG_DATA(nlh), data_buffer, data_length);
nlh->nlmsg_len = NLMSG_SPACE(data_length);
nlh->nlmsg_pid = 0; /* from kernel */
NETLINK_CB(nl_skb).pid = 0;
// destination 0 = PDCP, 1 = RRC
if (!destination) {
#ifdef NETLINK_DEBUG
printk("nasmt_netlink_send - nl_skb %p, nl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_nl_sk, nlh, nlh->nlmsg_len);
#endif //DEBUG_NETLINK
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
} else {
#ifdef NAS_DEBUG_RRCNL
printk("nasmt_rrcnl_send - nl_skb %p, nas_rrcnl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_rrcnl_sk, nlh, nlh->nlmsg_len);
#endif //NAS_DEBUG_RRCNL
status = netlink_unicast(nas_rrcnl_sk, nl_skb, NL_DEST_RRC_PID, MSG_DONTWAIT);
}
if (status < 0) {
printk("nasmt_netlink_send - SEND status is %d\n",status);
return(0);
} else {
#ifdef NETLINK_DEBUG
printk("nasmt_netlink_send - SEND status is %d, data_length %d\n",status, data_length);
#endif
return data_length;
}
}
@@ -1,122 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_proto.h
* \brief Function prototypes for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASMTD_PROTO_H
#define _NASMTD_PROTO_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
//#include "rrc_nas_primitives.h"
//#include "protocol_vars_extern.h"
//#include "as_sap.h"
//#include "rrc_qos.h"
//#include "rrc_sap.h"
// nasmt_netlink.c
void nasmt_netlink_release(void);
int nasmt_netlink_init(void);
int nasmt_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination);
// nasmt_common.c
//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlength, int sap);
void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
void nasmt_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
#ifndef PDCP_USE_NETLINK
void nasmt_COMMON_QOS_receive(struct cx_entity *cx);
#else
void nasmt_COMMON_QOS_receive(struct nlmsghdr *nlh);
#endif
struct rb_entity *nasmt_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rabi, nasQoSTrafficClass_t qos);
struct rb_entity *nasmt_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rabi);
struct cx_entity *nasmt_COMMON_search_cx(nasLocalConnectionRef_t lcr);
void nasmt_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp);
void nasmt_COMMON_flush_rb(struct cx_entity *cx);
//nasmt_ascontrol.c
void nasmt_ASCTL_init(void);
void nasmt_ASCTL_timer(unsigned long data);
int nasmt_ASCTL_DC_receive(struct cx_entity *cx, char *buffer);
int nasmt_ASCTL_GC_receive(char *buffer);
int nasmt_ASCTL_DC_send_cx_establish_request(struct cx_entity *cx);
int nasmt_ASCTL_DC_send_cx_release_request(struct cx_entity *cx);
void nasmt_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
void nasmt_ASCTL_DC_send_peer_sig_data_request(struct cx_entity *cx, uint8_t sig_category);
int nasmt_ASCTL_leave_sleep_mode(struct cx_entity *cx);
int nasmt_ASCTL_enter_sleep_mode(struct cx_entity *cx);
// nasmt_iocontrol.c
void nasmt_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
int nasmt_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
// nasmt_classifier.c
void nasmt_CLASS_send(struct sk_buff *skb);
struct classifier_entity *nasmt_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref);
struct classifier_entity *nasmt_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref);
void nasmt_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref);
void nasmt_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref);
void nasmt_CLASS_flush_sclassifier(struct cx_entity *cx);
void nasmt_CLASS_flush_rclassifier(void);
// nasmt_tool.c
uint8_t nasmt_TOOL_invfct(struct classifier_entity *gc);
void nasmt_TOOL_fct(struct classifier_entity *gc, uint8_t fct);
void nasmt_TOOL_imei2iid(uint8_t *imei, uint8_t *iid);
void nasmt_TOOL_eth_imei2iid(unsigned char *imei, unsigned char *addr ,unsigned char *iid, unsigned char len);
uint8_t nasmt_TOOL_get_dscp6(struct ipv6hdr *iph);
uint8_t nasmt_TOOL_get_dscp4(struct iphdr *iph);
uint8_t *nasmt_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol);
uint8_t *nasmt_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol);
void nasmt_TOOL_pk_icmp6(struct icmp6hdr *icmph);
void nasmt_TOOL_print_state(uint8_t state);
void nasmt_TOOL_print_buffer(unsigned char * buffer,int length);
void nasmt_TOOL_print_rb_entity(struct rb_entity *rb);
void nasmt_TOOL_print_classifier(struct classifier_entity *gc);
#endif
@@ -1,73 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_sap.h
* \brief SAP constants for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASMTD_SAP_H
#define _NASMTD_SAP_H
// RT-FIFO identifiers ** must be identical to Access Stratum as_sap.h and rrc_sap.h
#define RRC_DEVICE_GC RRC_SAPI_UE_GCSAP
#define RRC_DEVICE_NT RRC_SAPI_UE_NTSAP
#define RRC_DEVICE_DC_INPUT0 RRC_SAPI_UE_DCSAP_IN
#define RRC_DEVICE_DC_OUTPUT0 RRC_SAPI_UE_DCSAP_OUT
//#define QOS_DEVICE_CONVERSATIONAL_INPUT QOS_SAPI_CONVERSATIONAL_INPUT_MT
//#define QOS_DEVICE_CONVERSATIONAL_OUTPUT QOS_SAPI_CONVERSATIONAL_OUTPUT_MT
#define PDCP2PDCP_USE_RT_FIFO 21
#define NAS2PDCP_FIFO 22
//FIFO indexes in control blocks
#define NAS_DC_INPUT_SAPI 0
#define NAS_DC_OUTPUT_SAPI 1
#define NAS_SAPI_CX_MAX 2
#define NAS_GC_SAPI 0
#define NAS_NT_SAPI 1
#define NAS_DRB_INPUT_SAPI 2 //NAS_CO_INPUT_SAPI
#define NAS_DRB_OUTPUT_SAPI 3 //NAS_CO_OUTPUT_SAPI
#define NAS_SAPI_MAX 4
//#define NAS_QOS_CONVERSATIONAL UMTS_TRAFFIC_CONVERSATIONAL
//
/* Defined in RRC
#define RRC_NAS_GC_IN 0
#define RRC_NAS_GC_OUT 1
#define RRC_NAS_NT_IN 2
#define RRC_NAS_NT_OUT 3
#define RRC_NAS_DC0_IN 4
#define RRC_NAS_DC0_OUT 5
#define RRC_NAS_DC1_IN 6
#define RRC_NAS_DC1_OUT 7
#define RRC_NAS_DC2_IN 8
#define RRC_NAS_DC2_OUT 9
*/
#endif
@@ -1,494 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/***************************************************************************
nasmt_tool.c - description
***************************************************************************
***************************************************************************/
/*! \file nasmt_tool.c
* \brief Tool functions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasmt_variables.h"
#include "nasmt_proto.h"
//---------------------------------------------------------------------------
//
void nasmt_TOOL_fct(struct classifier_entity *gc, uint8_t fct)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_fct - begin \n");
#endif
if (gc==NULL) {
printk("nasmt_TOOL_fct - input parameter gc is NULL \n");
return;
}
// End debug information
switch(fct) {
case NAS_FCT_QOS_SEND:
gc->fct=nasmt_COMMON_QOS_send;
break;
case NAS_FCT_CTL_SEND:
gc->fct=nasmt_CTL_send;
break;
case NAS_FCT_DC_SEND:
gc->fct=nasmt_ASCTL_DC_send_sig_data_request;
break;
case NAS_FCT_DEL_SEND:
gc->fct=nasmt_COMMON_del_send;
break;
default:
gc->fct=nasmt_COMMON_del_send;
}
}
//---------------------------------------------------------------------------
uint8_t nasmt_TOOL_invfct(struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_invfct - begin \n");
#endif
if (gc==NULL) {
printk("nasmt_TOOL_invfct - input parameter gc is NULL \n");
return 0;
}
// End debug information
if (gc->fct==nasmt_COMMON_QOS_send)
return NAS_FCT_QOS_SEND;
if (gc->fct==nasmt_CTL_send)
return NAS_FCT_CTL_SEND;
if (gc->fct==nasmt_COMMON_del_send)
return NAS_FCT_DEL_SEND;
if (gc->fct==nasmt_ASCTL_DC_send_sig_data_request)
return NAS_FCT_DC_SEND;
return 0;
}
//---------------------------------------------------------------------------
uint8_t nasmt_TOOL_get_dscp6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_get_dscp6 - begin \n");
#endif
if (iph==NULL) {
printk("nasmt_TOOL_get_dscp6 - input parameter ipv6hdr is NULL \n");
return 0;
}
// End debug information
// return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>22; //Yan
return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>20;
}
//---------------------------------------------------------------------------
uint8_t nasmt_TOOL_get_dscp4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_get_dscp4 - begin \n");
#endif
if (iph==NULL) {
printk("nasmt_TOOL_get_dscp4 - input parameter ipv4hdr is NULL \n");
return 0;
}
// End debug information
return ((iph->tos)>>5)<<3;
}
//---------------------------------------------------------------------------
uint8_t *nasmt_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
uint16_t size;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_get_protocol6 - begin \n");
#endif
if (iph==NULL) {
printk("nasmt_TOOL_get_protocol6 - input parameter ipv6hdr is NULL \n");
return NULL;
}
if (protocol==NULL) {
printk("nasmt_TOOL_get_protocol6 - input parameter protocol is NULL \n");
return NULL;
}
// End debug information
*protocol=iph->nexthdr;
size=NAS_IPV6_SIZE;
while (1) {
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
return (uint8_t *)((uint8_t *)iph+size);
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]*8+8;
break;
case IPPROTO_FRAGMENT:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]+8;
break;
case IPPROTO_NONE:
case IPPROTO_AH:
case IPPROTO_ESP:
default:
return NULL;
}
}
}
//---------------------------------------------------------------------------
uint8_t *nasmt_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_get_protocol4 - begin \n");
#endif
if (iph==NULL) {
printk("nasmt_TOOL_get_protocol4 - input parameter iph is NULL \n");
return NULL;
}
if (protocol==NULL) {
printk("nasmt_TOOL_get_protocol4 - input parameter protocol is NULL \n");
return NULL;
}
// End debug information
*protocol=iph->protocol;
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
return (uint8_t *)((uint8_t *)iph+iph->tot_len);
default:
return NULL;
}
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void nasmt_TOOL_imei2iid(uint8_t *imei, uint8_t *iid)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_imei2iid - begin \n");
#endif
if (imei==NULL) {
printk("nasmt_TOOL_imei2iid - input parameter imei is NULL \n");
return;
}
if (iid==NULL) {
printk("nasmt_TOOL_imei2iid - input parameter iid is NULL \n");
return;
}
// End debug information
memset(iid, 0, NAS_ADDR_LEN);
iid[0] = 0x03;
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 16*imei[4]+imei[5];
iid[4] = 16*imei[6]+imei[7];
iid[5] = 16*imei[8]+imei[9];
iid[6] = 16*imei[10]+imei[11];
iid[7] = 16*imei[12]+imei[13];
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void nasmt_TOOL_eth_imei2iid(unsigned char *imei, unsigned char *addr ,unsigned char *iid, unsigned char len)
{
//---------------------------------------------------------------------------
unsigned int index;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_eth_imei2iid - begin \n");
#endif
if (!imei || !addr || !iid) {
printk("OAI_NW_DRV_TOOL_eNB_IMEI2IID - input parameter imei, addr or iid is NULL \n");
return;
}
// End debug information
// set addr (should be device HW address)
memset(addr, 0, len);
addr[0] = 0x00; // to be compatible between link local and global
// len -1 because of insertion of 0 above
for (index = 0; index < (len-1); index++) {
addr[index+1] = 16*imei[index*2]+imei[index*2+1];
}
// set iid6
memset(iid, 0, NAS_ADDR_LEN);
iid[0] = 0x02;
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 0xff;
iid[4] = 0xfe;
iid[5] = 16*imei[4]+imei[5];
iid[6] = 16*imei[6]+imei[7];
iid[7] = 16*imei[8]+imei[9];
}
//---------------------------------------------------------------------------
void nasmt_TOOL_pk_icmp6(struct icmp6hdr *icmph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef GRAAL_DEBUG_TOOL
printk("nasmt_TOOL_pk_icmp6 - begin \n");
#endif
if (!icmph) {
printk("nasmt_TOOL_pk_icmp6 - input parameter icmph is NULL \n");
return;
}
// End debug information
printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code);
switch(icmph->icmp6_type) {
case ICMPV6_DEST_UNREACH:
printk("Destination unreachable\n");
break;
case ICMPV6_PKT_TOOBIG:
printk("Packet too big\n");
break;
case ICMPV6_TIME_EXCEED:
printk("Time exceeded\n");
break;
case ICMPV6_PARAMPROB:
printk("Parameter problem\n");
break;
case ICMPV6_ECHO_REQUEST:
printk("Echo request\n");
break;
case ICMPV6_ECHO_REPLY:
printk("Echo reply\n");
break;
case ICMPV6_MGM_QUERY:
printk("Multicast listener query\n");
break;
case ICMPV6_MGM_REPORT:
printk("Multicast listener report\n");
break;
case ICMPV6_MGM_REDUCTION:
printk("Multicast listener done\n");
break;
case NDISC_ROUTER_SOLICITATION:
printk("Router solicitation\n");
break;
case NDISC_ROUTER_ADVERTISEMENT:
printk("Router advertisment\n");
break;
case NDISC_NEIGHBOUR_SOLICITATION:
printk("Neighbour solicitation\n");
break;
case NDISC_NEIGHBOUR_ADVERTISEMENT:
printk("Neighbour advertisment\n");
break;
case NDISC_REDIRECT:
printk("redirect message\n");
break;
}
}
//---------------------------------------------------------------------------
void nasmt_TOOL_print_state(uint8_t state)
{
//---------------------------------------------------------------------------
switch(state) {
case NAS_IDLE:
printk("NAS_IDLE\n");
return;
case NAS_CX_FACH:
printk("NAS_CX_FACH\n");
return;
case NAS_CX_DCH:
printk("NAS_CX_DCH\n");
return;
case NAS_CX_RECEIVED:
printk("NAS_CX_RECEIVED\n");
return;
case NAS_CX_CONNECTING:
printk("NAS_CX_CONNECTING\n");
return;
case NAS_CX_RELEASING:
printk("NAS_CX_RELEASING\n");
return;
case NAS_CX_CONNECTING_FAILURE:
printk("NAS_CX_CONNECTING_FAILURE\n");
return;
case NAS_CX_RELEASING_FAILURE:
printk("NAS_CX_RELEASING_FAILURE\n");
return;
case NAS_RB_ESTABLISHING:
printk("NAS_RB_ESTABLISHING\n");
return;
case NAS_RB_RELEASING:
printk("NAS_RB_RELEASING\n");
return;
case NAS_RB_DCH:
printk("NAS_RB_DCH\n");
return;
default:
printk("nasmt_TOOL_print_state - Unknown state\n");
}
}
//-----------------------------------------------------------------------------
// Print the content of a buffer in hexadecimal
void nasmt_TOOL_print_buffer(unsigned char * buffer,int length)
{
//-----------------------------------------------------------------------------
int i;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_print_buffer - begin \n");
#endif
if (buffer==NULL) {
printk("nasmt_TOOL_print_buffer - input parameter buffer is NULL \n");
return;
}
// End debug information
printk("\nBuffer content: ");
for (i=0; i<length; i++)
printk("-%hx-",buffer[i]);
printk(",\t length %d\n", length);
}
//-----------------------------------------------------------------------------
void nasmt_TOOL_print_rb_entity(struct rb_entity *rb)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_print_rb_entity - begin \n");
#endif
if (rb==NULL) {
printk("nasmt_TOOL_print_rb_entity - input parameter rb is NULL \n");
return;
}
// End debug information
printk("\nrb_entity content: rab_id %d, sapi %d, qos %d, dscp %d, \n", rb->rab_id, rb->sapi, rb->qos, rb->dscp);
printk("state %d, retry %d, countimer %d\n",rb->state, rb->retry, rb->countimer);
};
//-----------------------------------------------------------------------------
void nasmt_TOOL_print_classifier(struct classifier_entity *gc)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasmt_TOOL_print_classifier - begin \n");
#endif
if (gc==NULL) {
printk("nasmt_TOOL_print_classifier - input parameter gc is NULL \n");
return;
}
// End debug information
printk("\nClassifier content: classref %d, version %d, splen %d, dplen %d,\n", gc->classref, gc->version, gc->splen, gc->dplen);
printk("protocol %d, sport %d, dport %d, rab_id %d\n", gc->protocol, gc->sport, gc->dport, gc->rab_id);
nasmt_TOOL_print_rb_entity(gc->rb);
};
@@ -1,173 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_variables.h
* \brief Variable and structure definitions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASMTD_VAR_H
#define _NASMTD_VAR_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "rrc_nas_primitives.h"
#include "rrc_qos_classes.h"
#include "rrc_nas_sap.h"
#include "nasmt_constant.h"
#include "nasmt_sap.h"
struct cx_entity;
struct rb_entity {
uint32_t cnxid;
nasRadioBearerId_t rab_id; //ue_rbId
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
nasQoSTrafficClass_t RadioQosClass;
nasIPdscp_t dscp;
uint8_t state;
uint8_t result;
uint8_t retry;
uint32_t countimer;
struct rb_entity *next;
};
struct classifier_entity {
uint32_t classref; // classifier identity
uint8_t version; // IP version 4 or 6
union {
struct in6_addr ipv6;
uint32_t ipv4;
} saddr; // IP source address
uint8_t splen; // IP prefix size
union {
struct in6_addr ipv6;
uint32_t ipv4;
} daddr; // IP destination address
uint8_t dplen; // IP prefix size
uint8_t protocol; // layer 4 protocol type (tcp, udp, ...)
uint16_t sport; // source port
uint16_t dport; // destination port
struct rb_entity *rb;
nasRadioBearerId_t rab_id; // RAB identification
void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
struct classifier_entity *next;
};
struct cx_entity {
int sap[NAS_SAPI_CX_MAX];
uint8_t state; // state of the connection
nasLocalConnectionRef_t lcr; // Local connection reference
nasCellID_t cellid; // cell identification
uint32_t countimer; // timeout's counter
uint8_t retry; // number of retransmissions
struct classifier_entity *sclassifier[NAS_DSCP_MAX]; // send classifiers table
uint16_t nsclassifier;
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
struct rb_entity *rb;
uint16_t num_rb;
//measures
int req_prov_id[MAX_MEASURE_NB];
int num_measures;
int meas_cell_id[MAX_MEASURE_NB];
int meas_level[MAX_MEASURE_NB];
int provider_id[MAX_MEASURE_NB];
//MBMS
int joined_services[NASMT_MBMS_SVCES_MAX];
};
struct nas_priv {
int irq;
int rx_flags;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
uint8_t retry_limit;
uint32_t timer_establishment;
uint32_t timer_release;
struct cx_entity cx[NAS_CX_MAX];
struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier
uint16_t nrclassifier;
uint32_t next_sclassref;
int sap[NAS_SAPI_MAX];
uint8_t xbuffer[NAS_MAX_LENGTH]; // transmission buffer
uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer
};
struct ipversion {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t reserved:4,
version:4;
#else
uint8_t version:4,
reserved:4;
#endif
};
typedef struct pdcp_data_req_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_ind_header_t;
//
extern struct nas_priv *gpriv;
extern struct net_device *gdev;
//extern int bytes_wrote;
//extern int bytes_read;
extern uint8_t NAS_NULL_IMEI[14];
extern uint8_t NAS_RG_IMEI[14];
//global variables shared with RRC
extern int *pt_nas_ue_irq;
//extern uint8_t nas_IMEI[14];
#endif
@@ -1,79 +0,0 @@
# NAS CELLULAR Driver makefile
#
include $(OPENAIR_DIR)/common/utils/Makefile.inc
NAS_UPDIR := $(shell /bin/pwd)
####################################################
# D E B U G F L A G S
####################################################
####################################################
# EXTRA COMPILER FLAGS
####################################################
EXTRA_CFLAGS = -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,)
ifdef ADDRCONF
EXTRA_CFLAGS += -DADDRCONF
endif
ifdef NAS_DRIVER_TYPE_ETHERNET
EXTRA_CFLAGS += -DNAS_DRIVER_TYPE_ETHERNET
endif
ifdef PDCP_USE_NETLINK
EXTRA_CFLAGS += -DPDCP_USE_NETLINK
else
EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall
endif
ifdef LOOPBACK
EXTRA_CFLAGS += -DLOOPBACK_TEST
endif
ifdef ADDRESS_FIX
EXTRA_CFLAGS += -DNAS_ADDRESS_FIX
endif
####################################################
# NASRGCELL extra compilation flags
####################################################
#RTAI=1
RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR
EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_RG
####################################################
# LOADABLE MODULE GOALS
####################################################
obj-m += nascellrg.o
nascellrg-objs += nasrg_device.o
nascellrg-objs += nasrg_common.o
nascellrg-objs += nasrg_iocontrol.o
nascellrg-objs += nasrg_classifier.o
nascellrg-objs += nasrg_tool.o
nascellrg-objs += nasrg_ascontrol.o
ifdef PDCP_USE_NETLINK
nascellrg-objs += nasrg_netlink.o
endif
####################################################
# REVOIR LE CLEAN
####################################################
#netlink.ko:
#make $(x)$(y) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR) M=`pwd` modules
#nasmesh.ko:
# make V=1 -C $(KERNEL_DIR) M=`pwd` modules
print:
@echo RRC_DIR $(RRC_DIR)
clean:
rm -f *.ko
rm -f .*.ko.cmd
rm -f .*.o.cmd
rm -f *.o
rm -f *.mod.c
find . -name *.ko -delete
find . -name *.o -delete
find . -name *.mod.c -delete
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,628 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_common.c
* \brief Common functions for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasrg_variables.h"
#include "nasrg_proto.h"
#include <linux/inetdevice.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
//---------------------------------------------------------------------------
// Receive data from FIFO (QOS or DC)
//void nasrg_COMMON_receive(uint16_t hlen, uint16_t dlen, int sap){
void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap)
{
//---------------------------------------------------------------------------
struct sk_buff *skb;
struct ipversion *ipv;
unsigned int hard_header_len;
uint16_t *p_ether_type;
uint16_t ether_type;
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: begin\n");
#endif
#ifdef PDCP_USE_NETLINK
// data_buffer is NULL if FIFOs
if (!data_buffer) {
printk("nasrg_COMMON_receive - input parameter data_buffer is NULL \n");
return;
}
#endif
skb = dev_alloc_skb( payload_length + 2 );
if(!skb) {
printk("nasrg_COMMON_receive: low on memory\n");
++gpriv->stats.rx_dropped;
return;
}
skb_reserve(skb,2);
#ifndef PDCP_USE_NETLINK
bytes_read += rtf_get(sap, skb_put(skb, payload_length), payload_length);
if (bytes_read != NAS_PDCPH_SIZE + payload_length) {
printk("nasrg_COMMON_receive: problem while reading rtf sap\n");
kfree(skb->data);
dev_kfree_skb(skb);
return;
}
#else
memcpy(skb_put(skb, payload_length), data_buffer, payload_length);
bytes_read += payload_length;
#endif
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: received packet from PDCP, length %d\n", bytes_read);
#endif
skb->dev = gdev;
hard_header_len = gdev->hard_header_len;
skb->mac_header = skb->data;
skb->pkt_type = PACKET_HOST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
ipv = (struct ipversion *)&(skb->data[hard_header_len]);
switch (ipv->version) {
case 6:
#ifdef NAS_DEBUG_RECEIVE_BASIC
printk("nasrg_COMMON_receive: receive IPv6 message\n");
#endif
skb->network_header = &skb->data[hard_header_len];
// set protocol default value
skb->protocol = htons(ETH_P_IPV6);
// If type Ethernet, correct it
#ifdef NAS_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, gdev);
#endif
break;
case 4:
#ifdef NAS_DEBUG_RECEIVE_BASIC
printk("nasrg_COMMON_receive: receive IPv4 message\n");
#endif
#ifdef NAS_DEBUG_RECEIVE
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr;
if (addr) {
printk("nasrg_COMMON_receive: Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr;
if (addr) {
printk("nasrg_COMMON_receive Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
}
printk("nasrg_COMMON_receive protocol %d\n",((struct iphdr *)&skb->data[hard_header_len])->protocol);
#endif
skb->network_header = &skb->data[hard_header_len];
// set protocol default value
skb->protocol = htons(ETH_P_IP);
// If type Ethernet, correct it
#ifdef NAS_DRIVER_TYPE_ETHERNET
skb->protocol = eth_type_trans(skb, gdev);
#endif
break;
default:
printk("nasrg_COMMON_receive: Packet is not IPv4 or IPv6 (version=%d)\n", ipv->version);
#ifdef NAS_DRIVER_TYPE_ETHERNET
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: ether_type=%04X\n", ether_type);
#endif
skb->protocol = eth_type_trans(skb, gdev);
// minus 1(short) instead of 2(bytes) because uint16_t*
p_ether_type = (uint16_t *)&(skb->mac_header[hard_header_len-2]);
ether_type = ntohs(*p_ether_type);
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: ether_type=%04X\n", ether_type);
#endif
switch (ether_type) {
case ETH_P_ARP:
printk("nasrg_COMMON_receive: ether_type = ETH_P_ARP\n");
skb->protocol = htons(ETH_P_ARP);
skb->network_header = &skb->mac_header[hard_header_len];
break;
default:
break;
}
#endif
}
++gpriv->stats.rx_packets;
gpriv->stats.rx_bytes += bytes_read;
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: forwarding packet of size %d to kernel\n",skb->len);
#endif
netif_rx(skb);
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_receive: end\n");
#endif
}
//---------------------------------------------------------------------------
// Delete the data
void nasrg_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp)
{
//---------------------------------------------------------------------------
++gpriv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nasrg_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
struct pdcp_data_req_header_t pdcph;
int bytes_wrote = 0;
// Start debug information
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send - begin \n");
#endif
// if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
// {
// gpriv->stats.tx_dropped ++;
// printk("NAS_QOS_SEND: No connected, so message are dropped \n");
// return;
// }
if (!skb || !gc || !cx) {
printk("nasrg_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n");
return;
}
// End debug information
if (gc->rb==NULL) {
gc->rb=nasrg_COMMON_search_rb(cx, gc->rab_id);
if (gc->rb==NULL) {
++gpriv->stats.tx_dropped;
printk("nasrg_COMMON_QOS_send: No corresponding Radio Bearer, so message is dropped, rab_id=%u \n", gc->rab_id);
return;
}
}
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send #1 :");
printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id);
#endif
#ifdef NAS_DEBUG_SEND_DETAIL
nasrg_TOOL_print_classifier(gc);
#endif
pdcph.data_size = skb->len;
//pdcph.rb_id = (gc->rb)->rab_id+(NAS_RB_MAX_NUM*cx->lcr);
pdcph.rb_id = ((gc->rb)->rab_id)-NAS_SIG_NUM_SRB;
pdcph.inst = 0;
#ifdef PDCP_USE_NETLINK
bytes_wrote = nasrg_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len);
#endif
#else
//bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE);
bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len);
#endif
#endif //PDCP_USE_NETLINK
if (bytes_wrote != NAS_PDCPH_SIZE) {
printk("nasrg_COMMON_QOS_send: problem while writing PDCP's header\n");
printk("PDCP rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_COMMON_QOS_send #2 :");
printk("Header bytes written : %d\n", bytes_wrote);
#endif
#ifdef PDCP_USE_NETLINK
bytes_wrote += nasrg_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP);
#else
//bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len);
bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len);
#endif //PDCP_USE_NETLINK
if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) {
printk("nasrg_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion
printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send #3 :");
printk(" %d bytes written to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id, NAS2PDCP_FIFO);
#endif
gpriv->stats.tx_bytes += skb->len;
gpriv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_COMMON_QOS_send - end \n");
#endif
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nasrg_COMMON_QOS_send_test_netlink(struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct pdcp_data_req_header_t pdcph;
int bytes_wrote = 0;
// Start debug information
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send - begin \n");
#endif
// if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
// {
// gpriv->stats.tx_dropped ++;
// printk("NAS_QOS_SEND: No connected, so message are dropped \n");
// return;
// }
if (!skb ) {
printk("nasrg_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n");
return;
}
// End debug information
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send #1 :");
// printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id);
// nasrg_TOOL_print_classifier(gc);
#endif
pdcph.data_size = skb->len;
//pdcph.rb_id = (gc->rb)->rab_id+(NAS_RB_MAX_NUM*cx->lcr);
pdcph.rb_id = 6;
pdcph.inst = 0;
#ifdef PDCP_USE_NETLINK
bytes_wrote = nasrg_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP);
//printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len);
#else
//bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE);
bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE);
//printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len);
#endif //PDCP_USE_NETLINK
if (bytes_wrote != NAS_PDCPH_SIZE) {
printk("nasrg_COMMON_QOS_send: problem while writing PDCP's header\n");
// printk("PDCP rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send #2 :");
printk("Header bytes wrote : %d\n", bytes_wrote);
#endif
#ifdef PDCP_USE_NETLINK
bytes_wrote += nasrg_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP);
#else
//bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len);
bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len);
#endif //PDCP_USE_NETLINK
if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) {
printk("nasrg_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion
// printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
gpriv->stats.tx_dropped ++;
return;
}
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send #3 :");
printk(" %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id, NAS2PDCP_FIFO);
#endif
gpriv->stats.tx_bytes += skb->len;
gpriv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND
printk("nasrg_COMMON_QOS_send - end \n");
#endif
}
#ifndef PDCP_USE_NETLINK
//---------------------------------------------------------------------------
void nasrg_COMMON_QOS_receive(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
uint8_t sapi;
struct pdcp_data_ind_header_t pdcph;
int bytes_read = 0;
// Start debug information
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_QOS_receive - begin \n");
#endif
if (!cx) {
printk("nasrg_COMMON_QOS_receive - input parameter cx is NULL \n");
return;
}
// End debug information
// LG force the use of only 1 rt fifo
sapi = NAS_DRB_OUTPUT_SAPI;
bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE);
while (bytes_read>0) {
if (bytes_read != NAS_PDCPH_SIZE) {
printk("nasrg_COMMON_QOS_receive: problem while reading PDCP header\n");
return;
}
// data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer)
nasrg_COMMON_receive(NAS_PDCPH_SIZE, pdcph.data_size, NULL, pdcph->rb_id, gpriv->sap[sapi]);
// check if another frame is in the FIFO, otherwise return
bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE);
}
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_QOS_receive - end \n");
#endif
}
#else
//---------------------------------------------------------------------------
void nasrg_COMMON_QOS_receive(struct nlmsghdr *nlh)
{
//---------------------------------------------------------------------------
struct pdcp_data_ind_header_t *pdcph;
// Start debug information
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_QOS_receive - begin \n");
#endif
if (!nlh) {
printk("nasrg_COMMON_QOS_receive - input parameter nlh is NULL \n");
return;
}
// End debug information
pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh);
#ifdef NAS_DEBUG_RECEIVE
printk("nasrg_COMMON_QOS_receive - receive from PDCP, size %d, rab %d\\n", pdcph->data_size, pdcph->rb_id);
#endif //NAS_DEBUG_RECEIVE
//void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
nasrg_COMMON_receive(NAS_PDCPH_SIZE + pdcph->data_size, pdcph->data_size, (unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE, pdcph->rb_id, 0);
}
#endif //PDCP_USE_NETLINK
//---------------------------------------------------------------------------
struct cx_entity *nasrg_COMMON_search_cx(nasLocalConnectionRef_t lcr)
{
//---------------------------------------------------------------------------
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_search_cx - lcr %d\n",lcr);
#endif
if (lcr<NAS_CX_MAX)
return gpriv->cx+lcr;
else
return NULL;
}
//---------------------------------------------------------------------------
// Search a Radio Bearer
struct rb_entity *nasrg_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_search_rb - rab_id %d\n", rab_id);
#endif
if (cx==NULL) {
printk("nasrg_COMMON_search_rb - input parameter cx is NULL \n");
return NULL;
}
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
if (rb->rab_id==rab_id)
return rb;
}
return NULL;
}
//---------------------------------------------------------------------------
struct rb_entity *nasrg_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_add_rb - begin for rab_id %d , qos %d\n", rab_id, qos );
#endif
if (cx==NULL) {
printk("nasrg_COMMON_add_rb - input parameter cx is NULL \n");
return NULL;
}
rb=nasrg_COMMON_search_rb(cx, rab_id);
if (rb==NULL) {
rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL);
if (rb!=NULL) {
rb->retry=0;
rb->countimer=NAS_TIMER_IDLE;
rb->rab_id=rab_id;
// rb->rab_id=rab_id+(32*cx->lcr);
#ifdef NAS_DEBUG_DC
printk("nasrg_COMMON_add_rb: rb rab_id=%u, rab_id=%u, mt_id=%u\n",rb->rab_id,rab_id, cx->lcr);
#endif
// rb->dscp = NASRG_TEMP_2NDRAB_DSCP; //TEMP
rb->qos=qos;
rb->sapi=NAS_DRB_INPUT_SAPI;
// LG force the use of only one rt-fifo
// rb->sapi=NAS_BA_INPUT_SAPI;
rb->state=NAS_IDLE;
rb->next=cx->rb;
cx->rb=rb;
(cx->num_rb)++;
} else
printk("nasrg_COMMON_add_rb: no memory\n");
}
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_add_rb - end \n" );
#endif
return rb;
}
//---------------------------------------------------------------------------
// free the memory that has previously been allocated to rb and remove from linked list
void nasrg_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp)
{
//---------------------------------------------------------------------------
struct rb_entity *rb, *curr_rb, *prev_rb;
struct classifier_entity *p;
uint16_t classref=0;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_del_rb - begin\n");
#endif
if (cx==NULL) {
printk("nasrg_COMMON_del_rb - input parameter cx is NULL \n");
return;
}
// End debug information
// Clear the associated classifier
for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) {
if (p->classref>=classref) {
classref=p->classref;
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_del_rb: classifier found for dscp %u \n", dscp);
#endif
}
}
nasrg_CLASS_del_sclassifier(cx, dscp, classref);
// Now, delete the RB
curr_rb = NULL;
prev_rb = NULL;
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
if (rb->rab_id == rab_id) {
curr_rb = rb;
if (prev_rb!=NULL) {
prev_rb->next = rb->next;
} else {
cx->rb=rb->next;
}
break;
} else {
prev_rb = rb;
}
}
if (curr_rb!= NULL) {
printk("nasrg_COMMON_del_rb: del rab_id %u\n", rb->rab_id);
kfree(rb);
(cx->num_rb)--;
} else {
printk("\n\n--nasrg_COMMON_del_rb: ERROR, invalid rab_id %u\n", rb->rab_id);
}
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_del_rb - end\n");
#endif
}
//---------------------------------------------------------------------------
void nasrg_COMMON_flush_rb(struct cx_entity *cx)
{
//---------------------------------------------------------------------------
struct rb_entity *rb;
struct classifier_entity *gc;
uint8_t dscp;
// Start debug information
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_flush_rb - begin\n");
#endif
if (cx==NULL) {
printk("nasrg_COMMON_flush_rb - input parameter cx is NULL \n");
return;
}
// End debug information
for (rb=cx->rb; rb!=NULL; rb=cx->rb) {
printk("nasrg_COMMON_flush_rb: del rab_id %u\n", rb->rab_id);
cx->rb=rb->next;
kfree(rb);
}
cx->num_rb=0;
cx->rb=NULL;
for(dscp=0; dscp<NAS_DSCP_MAX; ++dscp) {
for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next)
gc->rb=NULL;
}
#ifdef NAS_DEBUG_CLASS
printk("nasrg_COMMON_flush_rb - end\n");
#endif
}
@@ -1,220 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_constant.h
* \brief Defines all constants for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASRGD_CST
#define _NASRGD_CST
//Debug flags
#define NAS_DEBUG_DC
//#define NAS_DEBUG_DC_DETAIL
#define NAS_DEBUG_SEND
//#define NAS_DEBUG_SEND_DETAIL // detail of packet transmission
//#define NAS_DEBUG_RECEIVE
#define NAS_DEBUG_RECEIVE_BASIC
#define NAS_DEBUG_CLASS
//#define NAS_DEBUG_CLASS_DETAIL
#define NAS_DEBUG_GC
//#define NAS_DEBUG_DC_MEASURE
//#define NAS_DEBUG_TIMER
#define NAS_DEBUG_DEVICE
//#define NAS_DEBUG_INTERRUPT
//#define NAS_DEBUG_TOOL
//#define NAS_DEBUG_MBMS_PROT //Only one RT-FIFO is used
#define NETLINK_DEBUG
#define NAS_DEBUG_RRCNL // RRC netlink socket
// Other flags
#define DEMO_3GSM
//#define NODE_RG
//#define NAS_AUTO_MBMS
// Begin default RAB
// Parameters for the default RAB started after network attachment (needs DEMO_3GSM defined)
// RBId value to be synchronized with RAL-RG
#define NASRG_DEFAULTRAB_RBID 6 //MW-01/01/07- RBID 5 => MBMS, 6 => DEFAULTRAB, 7+ => others
// Only one of next lines must be active - other values in l3/rrc/rrc_qos.h
#define NASRG_DEFAULTRAB_QoS 2 //MW-01/01/07- RRC_QOS_CONV_64_64
//#define NASRG_DEFAULTRAB_QoS 3 //MW-01/01/07- RRC_QOS_CONV_128_128
//#define NASRG_DEFAULTRAB_QoS 4 //MW-01/01/07- RRC_QOS_CONV_256_256
//#define NASRG_DEFAULTRAB_QoS 5 //MW-01/01/07- RRC_QOS_CONV_320_320
//#define NASRG_DEFAULTRAB_QoS 11 //LG RRC_QOS_INTER_128_64
//
#define NASRG_DEFAULTRAB_CLASSREF 1 //MW-01/01/07
#define NASRG_DEFAULTRAB_DSCP 0 //MW-01/01/07
#define NASRG_DEFAULTRAB_IPVERSION NAS_VERSION_DEFAULT //MW-01/01/07
// End default RAB
//Temp - hard coded
#define NASRG_OWN_CELLID 5
#define NASRG_TEMP_2NDRAB_DSCP 5
#define NASRG_TEMP_MBMS_SESSION_ID 1
#define NASRG_TEMP_MBMS_DURATION 999
#define NAS_DEFAULT_IPv6_PREFIX_LENGTH 128 // used to compare destination address with MT's
// General Constants
#define NAS_MTU 1500
#define NAS_TX_QUEUE_LEN 100
#define NAS_ADDR_LEN 8
#define NAS_INET6_ADDRSTRLEN 46
#define NAS_INET_ADDRSTRLEN 16
#define NAS_RESET_RX_FLAGS 0
#define NAS_CX_MAX 3 //Identical to RRC constant
//#define NAS_CX_MULTICAST_ALLNODE 2
#define NASRG_MBMS_SVCES_MAX 4 // Identical to RRC constant
#define NAS_RB_MAX_NUM 32 // maximum number of RBs per MT - 25.331
#define NAS_RETRY_LIMIT_DEFAULT 5
#define NAS_MESSAGE_MAXLEN 1600
// UMTS
#define NAS_SIG_SRB3 3
#define NAS_SIG_SRB4 3 // not used yet
//LTE
#define NAS_SIG_NUM_SRB 3 // number of srbs in LTE to send Rb_Id to PDCP
//peer-to-peer messages between NAS entities
#define NAS_CMD_OPEN_RB 1
#define NAS_CMD_ENTER_SLEEP 2
#define NAS_CMD_LEAVE_SLEEP 3
#define NAS_CX_RELEASE_UNDEF_CAUSE 1
// MT+RG NAS States
#define NAS_IDLE 0x01
// Connection
#define NAS_CX_FACH 0x06
#define NAS_CX_DCH 0x0A
#define NAS_CX_RECEIVED 0x10
#define NAS_CX_CONNECTING 0x04
#define NAS_CX_RELEASING 0x08
#define NAS_CX_CONNECTING_FAILURE 0x14
#define NAS_CX_RELEASING_FAILURE 0x18
// Radio Bearers
#define NAS_RB_ESTABLISHING 0x24
#define NAS_RB_RELEASING 0x28
#define NAS_RB_ESTABLISHED 0x2A
#define NAS_TIMER_ESTABLISHMENT_DEFAULT 12
#define NAS_TIMER_RELEASE_DEFAULT 2
#define NAS_TIMER_IDLE UINT_MAX
#define NAS_TIMER_TICK HZ
#define NAS_PDCPH_SIZE sizeof(struct pdcp_data_req_header_t)
#define NAS_IPV4_SIZE 20
#define NAS_IPV6_SIZE 40
#define NAS_DIRECTION_SEND 0
#define NAS_DIRECTION_RECEIVE 1
// function number
#define NAS_FCT_DEL_SEND 1
#define NAS_FCT_QOS_SEND 2
#define NAS_FCT_DC_SEND 3
#define NAS_FCT_CTL_SEND 4
// type of IOCTL command
#define NASRG_IOCTL_RAL 0x89F0
// Error cause
#define NAS_ERROR_ALREADYEXIST 1
#define NAS_ERROR_NOMEMORY 3
#define NAS_ERROR_NOTMT 9
#define NAS_ERROR_NOTRG 10
#define NAS_ERROR_NOTIDLE 11
#define NAS_ERROR_NOTCONNECTED 12
#define NAS_ERROR_NORB 14
#define NAS_ERROR_NOTCORRECTVALUE 32
#define NAS_ERROR_NOTCORRECTLCR 33
#define NAS_ERROR_NOTCORRECTDIR 34
#define NAS_ERROR_NOTCORRECTDSCP 35
#define NAS_ERROR_NOTCORRECTVERSION 36
#define NAS_ERROR_NOTCORRECTRABI 37
/**********************************************************/
/* Constants related with IP protocols */
/**********************************************************/
// Destination address types
#define NAS_IPV6_ADDR_UNICAST 1
#define NAS_IPV6_ADDR_MC_SIGNALLING 2
#define NAS_IPV6_ADDR_MC_MBMS 3
#define NAS_IPV6_ADDR_UNKNOWN 4
#define NAS_IPV4_ADDR_UNICAST 5
#define NAS_IPV4_ADDR_MC_SIGNALLING 6
#define NAS_IPV4_ADDR_BROADCAST 7
#define NAS_IPV4_ADDR_UNKNOWN 8
//#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000) Yan
#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0ff00000)
// Network control codepoint 111000 + IP version 6
#define NAS_FLOWINFO_NCONTROL __constant_htonl(0x6e000000)
// network control codepoint 111000
#define NAS_DSCP_NCONTROL 56 //0x38
// default codepoint 1000000
#define NAS_DSCP_DEFAULT 64
#define NAS_DSCP_MAX 65
#define NAS_PROTOCOL_DEFAULT 0
#define NAS_PROTOCOL_TCP IPPROTO_TCP
#define NAS_PROTOCOL_UDP IPPROTO_UDP
#define NAS_PROTOCOL_ICMP4 IPPROTO_ICMP
#define NAS_PROTOCOL_ICMP6 IPPROTO_ICMPV6
#define NAS_PORT_DEFAULT __constant_htons(65535)
#define NAS_PORT_HTTP __constant_htons(80)
#define NAS_VERSION_DEFAULT 0
#define NAS_VERSION_4 4
#define NAS_VERSION_6 6 //?MW
/**********************************************************/
/* Constants related with Netlink sockets */
/**********************************************************/
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
// defined in rrc_nas_sap.h
//#define NAS_RRCNL_ID 30
//#define NL_DEST_RRC_PID 2
#define NASNL_DEST_PDCP 0
#define NASNL_DEST_RRC 1
#endif
@@ -1,549 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_device.c
* \brief Networking Device Driver for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef PDCP_USE_NETLINK
#ifdef RTAI
#include "rtai_posix.h"
#define RTAI_IRQ 30 //try to get this irq with RTAI
#endif // RTAI
#endif // PDCP_USE_NETLINK
//:::::::::::::::::::::::::::::::::::::::;;
#include "nasrg_variables.h"
#include "nasrg_proto.h"
//:::::::::::::::::::::::::::::::::::::::;;
//#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/if_ether.h>
#endif
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <asm/unistd.h>
#include <linux/netdevice.h>
#ifdef NAS_DRIVER_TYPE_ETHERNET
#include <linux/etherdevice.h>
#endif
//:::::::::::::::::::::::::::::::::::::::;;
/* Global variables */
struct net_device *gdev;
struct nas_priv *gpriv;
//int bytes_wrote;
//int bytes_read;
uint8_t NAS_RG_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x01};
uint8_t NAS_NULL_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00};
uint16_t local_rg_cell_id;
#ifdef PDCP_USE_NETLINK
extern void nasrg_netlink_release(void);
extern int nasrg_netlink_init(void);
#endif
extern void nasrg_ASCTL_timer(unsigned long data);
#ifndef PDCP_USE_NETLINK
//---------------------------------------------------------------------------
void *nasrg_interrupt(void)
{
//---------------------------------------------------------------------------
uint8_t cxi;
#ifdef NAS_DEBUG_INTERRUPT
printk("nasrg_interrupt - begin\n");
#endif
//spin_lock(&gpriv->lock);
for (cxi=0; cxi<NAS_CX_MAX; ++cxi)
nasrg_COMMON_QOS_receive(gpriv->cx+cxi);
for (cxi=0; cxi<NAS_CX_MAX; ++cxi)
nasrg_ASCTL_DC_receive(gpriv->cx+cxi);
//spin_unlock(&gpriv->lock);
#ifdef NAS_DEBUG_INTERRUPT
printk("nasrg_interrupt: end\n");
#endif
// return 0;
}
#endif //NETLINK
//---------------------------------------------------------------------------
// Called by ifconfig when the device is activated by ifconfig
int nasrg_open(struct net_device *dev)
{
//---------------------------------------------------------------------------
printk("nasrg_open: begin\n");
gpriv=netdev_priv(dev);
// Address has already been set at init
#ifndef PDCP_USE_NETLINK
if (gpriv->irq==-EBUSY) {
printk("nasrg_open: irq failure\n");
return -EBUSY;
}
#endif //NETLINK
if(!netif_queue_stopped(dev))
netif_start_queue(dev);
else
netif_wake_queue(dev);
//
init_timer(&gpriv->timer);
(gpriv->timer).expires=jiffies+NAS_TIMER_TICK;
(gpriv->timer).data=0L;
(gpriv->timer).function=nasrg_ASCTL_timer;
add_timer(&gpriv->timer);
//
printk("nasrg_open: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
// Called by ifconfig when the device is desactivated by ifconfig
int nasrg_stop(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct nas_priv *priv = netdev_priv(dev);
printk("nasrg_stop: begin\n");
del_timer(&priv->timer);
netif_stop_queue(dev);
printk("nasrg_stop: name = %s, end\n", dev->name);
return 0;
}
//---------------------------------------------------------------------------
void nasrg_teardown(struct net_device *dev)
{
//---------------------------------------------------------------------------
int cxi;
#ifndef PDCP_USE_NETLINK
struct nas_priv *priv = netdev_priv(dev);
#endif //PDCP_USE_NETLINK
printk("nasrg_teardown: begin\n");
if (dev) {
#ifndef PDCP_USE_NETLINK
if (priv->irq!=-EBUSY) {
*pt_nas_rg_irq=-1;
rt_free_srq(priv->irq);
}
#endif //PDCP_USE_NETLINK
#ifdef PDCP_USE_NETLINK
nasrg_netlink_release();
#endif //PDCP_USE_NETLINK
// for (sapi=0; sapi<NAS_SAPI_MAX; ++sapi)
// close(priv->sap[sapi]);
nasrg_CLASS_flush_rclassifier();
nasrg_CLASS_flush_mbmsclassifier();
for (cxi=0; cxi<NAS_CX_MAX; ++cxi) {
nasrg_COMMON_flush_rb(gpriv->cx+cxi);
nasrg_CLASS_flush_sclassifier(gpriv->cx+cxi);
//for (sapi=0; sapi<NAS_SAPI_CX_MAX; ++sapi)
// close(priv->cx[cxi].sap[sapi]);
}
} // check dev
else {
printk("nasmt_teardown: Device is null\n");
}
printk("nasrg_teardown: end\n");
}
//---------------------------------------------------------------------------
int nasrg_set_config(struct net_device *dev, struct ifmap *map)
{
//---------------------------------------------------------------------------
printk("nasrg_set_config: begin\n");
if (dev->flags & IFF_UP)
return -EBUSY;
if (map->base_addr != dev->base_addr) {
printk(KERN_WARNING "nasrg_set_config: Can't change I/O address\n");
return -EOPNOTSUPP;
}
if (map->irq != dev->irq)
dev->irq = map->irq;
return 0;
}
//---------------------------------------------------------------------------
int nasrg_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_DEVICE
printk("nasrg_hard_start_xmit: begin\n");
#endif
if ((!skb )||(!dev)) {
printk("nasrg_hard_start_xmit - input parameter skb or dev is NULL \n");
return -1;
}
// End debug information
netif_stop_queue(dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_hard_start_xmit: step 1\n");
#endif
nasrg_CLASS_send(skb);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_hard_start_xmit: step 2\n");
#endif
dev_kfree_skb(skb);
#ifdef NAS_DEBUG_SEND_DETAIL
printk("nasrg_hard_start_xmit: step 3\n");
#endif
netif_wake_queue(dev);
#ifdef NAS_DEBUG_DEVICE
printk("nasrg_hard_start_xmit: end\n");
#endif
return 0;
}
//---------------------------------------------------------------------------
struct net_device_stats *nasrg_get_stats(struct net_device *dev)
{
//---------------------------------------------------------------------------
struct nas_priv *npriv = netdev_priv(dev);
return &npriv->stats;
}
//---------------------------------------------------------------------------
// New function from LITE DRIVER
int nasrg_set_mac_address(struct net_device *dev, void *mac)
{
//---------------------------------------------------------------------------
struct sockaddr *addr = mac;
printk("nasrg_set_mac_address: begin\n");
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
return 0;
}
//---------------------------------------------------------------------------
int nasrg_change_mtu(struct net_device *dev, int mtu)
{
//---------------------------------------------------------------------------
printk("nasrg_change_mtu: begin\n");
if ((mtu<50) || (mtu>1500))
// if ((mtu<1280) || (mtu>1500))
return -EINVAL;
dev->mtu = mtu;
return 0;
}
//---------------------------------------------------------------------------
int nasrg_change_rx_flags(struct net_device *dev, int flags)
{
//---------------------------------------------------------------------------
//struct nas_priv *priv = netdev_priv(dev);
printk("nasrg_change_rx_flags %08X\n", flags);
gpriv->rx_flags ^= flags;
return 0;
}
//---------------------------------------------------------------------------
void nasrg_tx_timeout(struct net_device *dev)
{
//---------------------------------------------------------------------------
/* Transmitter timeout, serious problems. */
printk("nasrg_tx_timeout: begin\n");
// ((struct nas_priv *)(dev->priv))->stats.tx_errors++;
(gpriv->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev);
#else
dev->trans_start = jiffies;
#endif
netif_wake_queue(dev);
printk("nasrg_tx_timeout: transmit timed out %s\n",dev->name);
}
//---------------------------------------------------------------------------
// Define pointers for the module
static const struct net_device_ops nasrg_netdev_ops = {
// ?? nasrg_ interrupt
//
.ndo_open = nasrg_open,
.ndo_stop = nasrg_stop,
.ndo_start_xmit = nasrg_hard_start_xmit,
.ndo_validate_addr = NULL,
.ndo_get_stats = nasrg_get_stats,
//#ifdef KERNEL_VERSION_GREATER_THAN_32
// .ndo_set_multicast_list = NULL,
.ndo_set_mac_address = nasrg_set_mac_address,
.ndo_set_config = nasrg_set_config,
.ndo_do_ioctl = nasrg_CTL_ioctl,
.ndo_change_mtu = nasrg_change_mtu,
.ndo_tx_timeout = nasrg_tx_timeout,
.ndo_change_rx_flags = nasrg_change_rx_flags,
//#endif
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Initialisation of the network device
void nasrg_init(struct net_device *dev)
{
//---------------------------------------------------------------------------
uint8_t cxi, dscpi;
printk("nasrg_init: begin\n");
if (dev) {
gpriv=netdev_priv(dev);
memset(gpriv, 0, sizeof(struct nas_priv));
// Initialize function pointers
dev->netdev_ops = &nasrg_netdev_ops;
#ifndef NAS_DRIVER_TYPE_ETHERNET
dev->type = ARPHRD_EURUMTS;
dev->features = NETIF_F_NO_CSUM;
dev->hard_header_len = 0;
dev->addr_len = NAS_ADDR_LEN;
dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
dev->tx_queue_len = NAS_TX_QUEUE_LEN;
dev->mtu = NAS_MTU;
#endif
// Can be one of the following enum defined in include/linux/netdevice.h:
// enum netdev_state_t {
// __LINK_STATE_START,
// __LINK_STATE_PRESENT,
// __LINK_STATE_NOCARRIER,
// __LINK_STATE_LINKWATCH_PENDING,
// __LINK_STATE_DORMANT,
// };
set_bit(__LINK_STATE_PRESENT, &dev->state);
#ifdef NAS_DRIVER_TYPE_ETHERNET
// overwrite values written above ( header_ops,type,hard_header_len,mtu,addr_len,tx_queue_len,flags,broadcast)
printk("\nnasrg_init: WARNING Driver type ETHERNET\n");
ether_setup(dev);
#endif
//
// Initialize private structure
gpriv->rx_flags = NAS_RESET_RX_FLAGS;
gpriv->sap[NAS_GC_SAPI] = RRC_DEVICE_GC;
gpriv->sap[NAS_NT_SAPI] = RRC_DEVICE_NT;
gpriv->cx[0].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0;
gpriv->cx[0].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0;
gpriv->cx[1].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT1;
gpriv->cx[1].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT1;
// gpriv->sap[NAS_CO_INPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_INPUT;
// gpriv->sap[NAS_CO_OUTPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_OUTPUT;
gpriv->sap[NAS_DRB_INPUT_SAPI] = PDCP2PDCP_USE_RT_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT;
gpriv->sap[NAS_DRB_OUTPUT_SAPI] = NAS2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT;
//
gpriv->retry_limit=NAS_RETRY_LIMIT_DEFAULT;
gpriv->timer_establishment=NAS_TIMER_ESTABLISHMENT_DEFAULT;
gpriv->timer_release=NAS_TIMER_RELEASE_DEFAULT;
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi)
gpriv->rclassifier[dscpi]=NULL;
gpriv->nrclassifier=0;
//
for(cxi=0; cxi<NAS_CX_MAX; ++cxi) {
#ifdef NAS_DEBUG_DEVICE
printk("nasrg_init: init classifiers, state and timer for MTs %u\n", cxi);
#endif
gpriv->cx[cxi].state=NAS_IDLE;
gpriv->cx[cxi].countimer=NAS_TIMER_IDLE;
gpriv->cx[cxi].retry=0;
gpriv->cx[cxi].lcr=cxi;
gpriv->cx[cxi].rb=NULL;
gpriv->cx[cxi].num_rb=0;
// initialisation of the classifier
for (dscpi=0; dscpi<NAS_DSCP_MAX; ++dscpi)
gpriv->cx[cxi].sclassifier[dscpi]=NULL;
gpriv->cx[cxi].nsclassifier=0;
// initialisation of the IP address
nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)gpriv->cx[cxi].iid6);
gpriv->cx[cxi].iid4=0;
}
spin_lock_init(&gpriv->lock);
nasrg_TOOL_RGimei2iid(NAS_RG_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address)
printk("nasrg_init: init IMEI to IID\n");
nasrg_ASCTL_init();
} else {
printk("\n\nnasmt_init: ERROR, Device is NULL!!\n");
}
printk("nasrg_init: end\n");
return ;
}
//---------------------------------------------------------------------------
int init_module (void)
{
//---------------------------------------------------------------------------
int err;
int inst = 0;
struct nas_priv *priv;
char devicename[100];
printk("\n\n\n\nnasrg_init_module: begin \n");
// Initialize parameters shared with RRC
#ifndef PDCP_USE_NETLINK
if (pt_nas_rg_irq==NULL) {
printk("nasrg_init_module: shared irq parameter not initialised\n");
err = -EBUSY;
printk("nasrg_init_module: returning %d \n\n", err);
return err;
}
printk("nasrg_init_module: pt_nas_rg_irq valid \n");
#endif
/*
if (pt_rg_own_cell_id==NULL){
printk("nasrg_init_module: shared cell_id parameter not initialised\n");
err = -EBUSY;
printk("nasrg_init_module: returning %d \n\n\n", err);
return err;
}
printk("nasrg_init_module: pt_rg_own_cell_id valid \n");
*pt_rg_own_cell_id = NASRG_OWN_CELLID;
*/
local_rg_cell_id = NASRG_OWN_CELLID;
// Allocate device structure
sprintf(devicename,"oai%d",inst);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
gdev = alloc_netdev(sizeof(struct nas_priv), devicename, nasrg_init);
#else
gdev = alloc_netdev(sizeof(struct nas_priv), devicename, NET_NAME_PREDICTABLE, nasrg_init);
#endif
printk("nasrg_init_module: after alloc_netdev \n");
priv = netdev_priv(gdev);
////
//
#ifndef PDCP_USE_NETLINK
priv->irq=rt_request_srq(0, nasrg_interrupt, NULL);
if (priv->irq == -EBUSY || priv->irq == -EINVAL) {
printk("nasrg_init_module: No interrupt resource available\n");
if (gdev) {
free_netdev(gdev);
printk("nasrg_init_module: free_netdev ..\n");
}
return -EBUSY;
} else
printk("nasrg_init_module: Interrupt %d, ret = %d \n", priv->irq , ret);
if (pt_nas_rg_irq==NULL) {
printk("nasmt_init_module: shared irq parameter has been reset\n");
} else {
*pt_nas_rg_irq=priv->irq;
}
#endif
//
//////
#ifdef PDCP_USE_NETLINK
if ((err=nasrg_netlink_init()) < 0)
printk("nasrg_init_module: NETLINK failed\n");
printk("nasrg_init_module: NETLINK INIT successful\n");
#endif //NETLINK
err= register_netdev(gdev);
if (err) {
printk("nasrg_init_module: error %i registering device %s\n", err, gdev->name);
} else {
printk("nasrg_init_module: registering device %s, ifindex = %d\n\n",gdev->name, gdev->ifindex);
}
return err;
}
//---------------------------------------------------------------------------
void cleanup_module(void)
{
//---------------------------------------------------------------------------
printk("nasrg_cleanup_module: begin\n");
unregister_netdev(gdev);
nasrg_teardown(gdev);
free_netdev(gdev);
printk("nasrg_cleanup_module: end\n\n\n\n");
}
//---------------------------------------------------------------------------
// Replaced by init_module and cleanup_module
//module_init (nasrg_init_module);
//module_exit (nasrg_cleanup_module);
//---------------------------------------------------------------------------
#define DRV_NAME "oai_nasrg"
#define DRV_VERSION "3.0.1"DRV_NAME
#define DRV_DESCRIPTION "OPENAIR CELLULAR LTE NASRG (eNodeB) Device Driver"
#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2013"
#define DRV_AUTHOR "Michelle Wetterwald <michelle.wetterwald@eurecom.fr>"DRV_COPYRIGHT
// MODULE_LICENSE("GPL");
// MODULE_DESCRIPTION("LTE Driver for eNodeB, playing as Non Access Stratum");
// MODULE_AUTHOR("Michelle Wetterwald <michelle.wetterwald@eurecom.fr>");
@@ -1,906 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_iocontrol.c
* \brief I/O control functions for upper layers of driver for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#include "nasrg_variables.h"
#include "nasrg_iocontrol.h"
#include "nasrg_proto.h"
//#include <linux/in.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/uaccess.h>
// Statistic
///////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
void nasrg_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep)
{
//---------------------------------------------------------------------------
msgrep->rx_packets=gpriv->stats.rx_packets;
msgrep->tx_packets=gpriv->stats.tx_packets;
msgrep->rx_bytes=gpriv->stats.rx_bytes;
msgrep->tx_bytes=gpriv->stats.tx_bytes;
msgrep->rx_errors=gpriv->stats.rx_errors;
msgrep->tx_errors=gpriv->stats.tx_errors;
msgrep->rx_dropped=gpriv->stats.rx_dropped;
msgrep->tx_dropped=gpriv->stats.tx_dropped;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_statistic_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_statistic_reply msgrep;
printk("nasrg_ioCTL_statistic: stat requested\n");
nasrg_set_msg_statistic_reply(&msgrep);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_statistic: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connections List
//---------------------------------------------------------------------------
void nasrg_set_msg_cx_list_reply(uint8_t *msgrep)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
nasLocalConnectionRef_t lcr;
struct nas_msg_cx_list_reply *list;
msgrep[0]=NAS_CX_MAX;
list=(struct nas_msg_cx_list_reply *)(msgrep+1);
for(lcr=0; lcr<NAS_CX_MAX; ++lcr) {
cx=nasrg_COMMON_search_cx(lcr);
list[lcr].lcr=lcr;
list[lcr].state=cx->state;
list[lcr].cellid=cx->cellid;
list[lcr].iid4=cx->iid4;
list[lcr].iid6[0]=cx->iid6[0];
list[lcr].iid6[1]=cx->iid6[1];
list[lcr].num_rb=cx->num_rb;
list[lcr].nsclassifier=cx->nsclassifier;
printk("nasrg_set_msg_cx_list: nsc=%u\n",cx->nsclassifier);
}
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_cx_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1];
printk("nasrg_ioCTL_cx_list: connection list requested\n");
nasrg_set_msg_cx_list_reply(msgrep);
if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) {
printk("nasrg_ioCTL_cx_list: copy_to_user failure\n");
return -EFAULT;
}
printk("nasrg_ioCTL_cx_list: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Establishment
//---------------------------------------------------------------------------
void nasrg_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep, struct nas_msg_cx_establishment_request *msgreq)
{
//---------------------------------------------------------------------------
msgrep->status=-NAS_ERROR_NOTMT;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_cx_establishment_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_establishment_request msgreq;
struct nas_msg_cx_establishment_reply msgrep;
printk("nasrg_ioCTL_cx_establishment: connection establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_cx_establishment: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_cx_establishment_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_cx_establishment: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Connection Release
//---------------------------------------------------------------------------
void nasrg_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep, struct nas_msg_cx_release_request *msgreq)
{
//---------------------------------------------------------------------------
msgrep->status=-NAS_ERROR_NOTMT;
}
//---------------------------------------------------------------------------
// Request the release of a connection
int nasrg_ioCTL_cx_release_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_cx_release_request msgreq;
struct nas_msg_cx_release_reply msgrep;
printk("nasrg_set_msg_cx_release: connection release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_set_msg_cx_release: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_cx_release_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_set_msg_cx_release: copy_to_user failure\n");
return -EFAULT;
}
printk("nasrg_set_msg_cx_release: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer List
//---------------------------------------------------------------------------
void nasrg_set_msg_rb_list_reply(uint8_t *msgrep, struct nas_msg_rb_list_request *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
uint8_t rbi;
struct rb_entity *rb;
struct nas_msg_rb_list_reply *list;
if (cx->num_rb > NAS_LIST_RB_MAX)
msgrep[0] = NAS_LIST_RB_MAX;
else
msgrep[0] = cx->num_rb;
list=(struct nas_msg_rb_list_reply *)(msgrep+1);
// list all radio bearers
for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbi<msgrep[0]); rb=rb->next, ++rbi) {
list[rbi].state=rb->state;
list[rbi].rab_id=rb->rab_id;
list[rbi].sapi=rb->sapi;
list[rbi].qos=rb->qos;
list[rbi].cnxid=rb->cnxid;
}
// check if mt0 requested and multicast bearer started, then add it to the list
if ((msgreq->lcr==0)&&(gpriv->mbms_rb[0].mbms_rbId!=0)) {
printk("MT %d, MBMS bearer rb_id %d\n", msgreq->lcr, gpriv->mbms_rb[0].mbms_rbId);
//++rbi;
++msgrep[0];
list[rbi].state=gpriv->mbms_rb[0].state;
list[rbi].rab_id=gpriv->mbms_rb[0].mbms_rbId;
list[rbi].sapi=gpriv->mbms_rb[0].sapi;
list[rbi].qos=gpriv->mbms_rb[0].qos;
list[rbi].cnxid=gpriv->mbms_rb[0].cnxid;
printk("rab_id cnxid Sapi QoS State\n");
printk("%u %u %u %u ", list[rbi].rab_id,list[rbi].cnxid, list[rbi].sapi, list[rbi].qos);
nasrg_TOOL_print_state(list[rbi].state);
printk("\n");
}
} else
msgrep[0]=0;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_rb_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1];
struct nas_msg_rb_list_request msgreq;
printk("nasrg_ioCTL_rb_list: Radio Bearer list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_rb_list: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_rb_list_reply(msgrep, &msgreq);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) {
printk("nasrg_ioCTL_rb_list: copy_to_user failure\n");
return -EFAULT;
}
printk("nasrg_ioCTL_rb_list: end\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Establishment
//---------------------------------------------------------------------------
void nasrg_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep, struct nas_msg_rb_establishment_request *msgreq)
{
//---------------------------------------------------------------------------
if ((msgreq->rab_id<5)||(msgreq->rab_id>(NAS_RB_MAX_NUM-1)))
msgrep->status=-NAS_ERROR_NOTCORRECTRABI;
else {
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) { //not multicast
struct rb_entity *rb;
rb=nasrg_COMMON_add_rb(cx, msgreq->rab_id, msgreq->qos);
if (rb!=NULL) {
rb->cnxid = msgreq->cnxid;
rb->dscp = msgreq->dscp_dl;
rb->dscp_ul = msgreq->dscp_ul;
msgrep->status=nasrg_ASCTL_DC_send_rb_establish_request(cx, rb);
} else {
msgrep->status=-NAS_ERROR_NOMEMORY;
}
} else { //no MT found
if (msgreq->mcast_flag) { //multicast
int mbms_ix=0; // should allocate index based on Service_id /cnxid / MC IP address
//
gpriv->mbms_rb[mbms_ix].cnxid = msgreq->cnxid;
gpriv->mbms_rb[mbms_ix].serviceId = msgreq->cnxid;
gpriv->mbms_rb[mbms_ix].sessionId = NASRG_TEMP_MBMS_SESSION_ID; //Temp hard coded
gpriv->mbms_rb[mbms_ix].mbms_rbId = msgreq->rab_id;
gpriv->mbms_rb[mbms_ix].sapi = NAS_DC_INPUT_SAPI;
#ifdef NAS_DEBUG_MBMS_PROT
gpriv->mbms_rb[mbms_ix].sapi = NAS_DRB_INPUT_SAPI; //Only one RT-FIFO is used
#endif
gpriv->mbms_rb[mbms_ix].qos = msgreq->qos;
gpriv->mbms_rb[mbms_ix].dscp = msgreq->dscp_dl;
gpriv->mbms_rb[mbms_ix].duration = NASRG_TEMP_MBMS_DURATION; //Temp hard coded
memcpy ((char *)&(gpriv->mbms_rb[mbms_ix].mcast_address),(char *)&(msgreq->mcast_group), 16);
msgrep->status=nasrg_ASCTL_GC_send_mbms_bearer_establish_req(mbms_ix);
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
}
msgrep->cnxid = msgreq->cnxid;
}
}
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_rb_establishment_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_establishment_request msgreq;
struct nas_msg_rb_establishment_reply msgrep;
printk("nasrg_ioCTL_rb_establishment: Radio bearer establishment requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_rb_establishment: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_rb_establishment_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_rb_establishment: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Radio Bearer Release
//---------------------------------------------------------------------------
void nasrg_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep, struct nas_msg_rb_release_request *msgreq)
{
//---------------------------------------------------------------------------
if (msgreq->lcr<NAS_CX_MAX) {
if (msgreq->rab_id!=NASRG_DEFAULTRAB_RBID) {
struct rb_entity *rb;
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->lcr);
rb=nasrg_COMMON_search_rb(cx, msgreq->rab_id);
if ((rb!=NULL)&&(cx!=NULL)) {
uint8_t dscp;
msgrep->status=nasrg_ASCTL_DC_send_rb_release_request(cx, rb);
dscp=rb->dscp;
nasrg_COMMON_del_rb(cx, msgreq->rab_id, dscp);
} else
msgrep->status=-NAS_ERROR_NOTCONNECTED;
msgrep->cnxid = msgreq->cnxid;
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTRABI;
}
} else {
if (msgreq->mcast_flag) { // multicast
int mbms_ix=0; // should search mbms_ix based on cnxid
msgrep->status=nasrg_ASCTL_GC_send_mbms_bearer_release_req(mbms_ix);
msgrep->cnxid = msgreq->cnxid;
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
}
}
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_rb_release_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_rb_release_request msgreq;
struct nas_msg_rb_release_reply msgrep;
printk("nasrg_ioCTL_rb_release: Radio bearer release requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_rb_release: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_rb_release_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_rb_release: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Classifier List
//---------------------------------------------------------------------------
void nasrg_set_msg_class_list_reply(uint8_t *msgrep, struct nas_msg_class_list_request *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
struct classifier_entity *gc;
struct nas_msg_class_list_reply *list;
uint8_t cli;
list=(struct nas_msg_class_list_reply *)(msgrep+1);
switch(msgreq->dir) {
case NAS_DIRECTION_SEND:
cx=nasrg_COMMON_search_cx(msgreq->lcr);
if (cx==NULL) {
msgrep[0]=0;
return;
}
gc=cx->sclassifier[msgreq->dscp];
break;
case NAS_DIRECTION_RECEIVE:
cx=NULL;
gc=gpriv->rclassifier[msgreq->dscp];
break;
default:
cx=NULL;
msgrep[0]=0;
return;
}
for (cli=0; (gc!=NULL)&&(cli<NAS_LIST_CLASS_MAX); gc=gc->next, ++cli) {
list[cli].classref=gc->classref;
list[cli].lcr=msgreq->lcr;
list[cli].dir=msgreq->dir;
list[cli].dscp=msgreq->dscp;
list[cli].rab_id=gc->rab_id;
list[cli].version=gc->version;
switch(gc->version) {
case 4:
list[cli].saddr.ipv4 = gc->saddr.ipv4;
list[cli].daddr.ipv4 = gc->daddr.ipv4;
break;
case 6:
list[cli].saddr.ipv6 = gc->saddr.ipv6;
list[cli].daddr.ipv6 = gc->daddr.ipv6;
break;
}
list[cli].protocol=gc->protocol;
list[cli].sport=ntohs(gc->sport);
list[cli].dport=ntohs(gc->dport);
list[cli].splen=gc->splen;
list[cli].dplen=gc->dplen;
list[cli].fct=nasrg_TOOL_invfct(gc);
}
msgrep[0]=cli;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_class_list_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1];
struct nas_msg_class_list_request msgreq;
printk("nasrg_ioCTL_class_list: classifier list requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_class_list: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_class_list_reply(msgrep, &msgreq);
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) {
printk("nasrg_ioCTL_class_list: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the addition of a classifier rule
//---------------------------------------------------------------------------
void nasrg_set_msg_class_add_reply(struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq)
{
//---------------------------------------------------------------------------
struct classifier_entity *gc;
if (msgreq->dscp>NAS_DSCP_DEFAULT) {
printk("nasrg_set_msg_class_add: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL) {
printk("nasrg_set_msg_class_add: DSCP %d, Classref %d\n",msgreq->dscp, msgreq->classref );
gc=nasrg_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref);
printk("nasrg_set_msg_class_add: %p %p\n" , msgreq, gc);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
gc->rab_id=msgreq->rab_id;
gc->rb=nasrg_COMMON_search_rb(cx, gc->rab_id);
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE) {
gc=nasrg_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref);
if (gc==NULL) {
msgrep->status=-NAS_ERROR_NOMEMORY;
return;
}
} else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
}
nasrg_TOOL_fct(gc, msgreq->fct);
gc->version=msgreq->version;
switch(gc->version) {
case 4:
gc->saddr.ipv4=msgreq->saddr.ipv4;
gc->daddr.ipv4=msgreq->daddr.ipv4;
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case 6:
gc->saddr.ipv6=msgreq->saddr.ipv6;
gc->daddr.ipv6=msgreq->daddr.ipv6;
gc->splen=msgreq->splen;
gc->dplen=msgreq->dplen;
break;
case 0:
gc->saddr.ipv6.s6_addr32[0]=0;
gc->daddr.ipv6.s6_addr32[1]=0;
gc->saddr.ipv6.s6_addr32[2]=0;
gc->daddr.ipv6.s6_addr32[3]=0;
gc->splen=0;
gc->dplen=0;
break;
default:
msgrep->status=-NAS_ERROR_NOTCORRECTVERSION;
kfree(gc);
return;
}
gc->protocol=msgreq->protocol;
gc->sport=htons(msgreq->sport);
gc->dport=htons(msgreq->dport);
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_class_add_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_class_add_request msgreq;
struct nas_msg_class_add_reply msgrep;
printk("nasrg_ioCTL_class_add: Add classifier components requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_class_add: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_class_add_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_class_add: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Request the deletion of a classifier rule
//---------------------------------------------------------------------------
void nasrg_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep, struct nas_msg_class_del_request *msgreq)
{
//---------------------------------------------------------------------------
if (msgreq->dscp>NAS_DSCP_DEFAULT) {
printk("nasrg_set_msg_class_del: Incoherent parameter value\n");
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
return;
}
if (msgreq->dir==NAS_DIRECTION_SEND) {
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->lcr);
if (cx!=NULL)
nasrg_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
return;
}
} else {
if (msgreq->dir==NAS_DIRECTION_RECEIVE)
nasrg_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref);
else {
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
return;
}
}
msgrep->status=0;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_class_del_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_class_del_request msgreq;
struct nas_msg_class_del_reply msgrep;
printk("nasrg_ioCTL_class_del: Del classifier components requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_class_del: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_class_del_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_class_del: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// UE Multicast Join
//---------------------------------------------------------------------------
void nasrg_set_ue_multicast_join_reply(struct nas_msg_mt_mcast_reply *msgrep, struct nas_msg_mt_mcast_join *msgreq)
{
//---------------------------------------------------------------------------
if (msgreq->ue_id<NAS_CX_MAX) {
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->ue_id);
cx->requested_joined_services[0] = msgreq->cnxid;
msgrep->ue_id = msgreq->ue_id;
msgrep->result = nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx);
msgrep->cnxid = msgreq->cnxid;
} else {
msgrep->result=-NAS_ERROR_NOTCORRECTLCR;
}
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_ue_multicast_join_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_mt_mcast_join msgreq;
struct nas_msg_mt_mcast_reply msgrep;
printk("nasrg_ioCTL_ue_multicast_join: UE multicast join requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_ue_multicast_join: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_ue_multicast_join_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_ue_multicast_join: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// UE Multicast Leave
//---------------------------------------------------------------------------
void nasrg_set_ue_multicast_leave_reply(struct nas_msg_mt_mcast_reply *msgrep, struct nas_msg_mt_mcast_leave *msgreq)
{
//---------------------------------------------------------------------------
if (msgreq->ue_id<NAS_CX_MAX) {
struct cx_entity *cx;
cx=nasrg_COMMON_search_cx(msgreq->ue_id);
cx->requested_left_services[0] = msgreq->cnxid;
msgrep->ue_id = msgreq->ue_id;
msgrep->result = nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx);
msgrep->cnxid = msgreq->cnxid;
} else {
msgrep->result=-NAS_ERROR_NOTCORRECTLCR;
}
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_ue_multicast_leave_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_mt_mcast_leave msgreq;
struct nas_msg_mt_mcast_reply msgrep;
printk("nasrg_ioCTL_ue_multicast_leave: UE multicast leave requested\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_ue_multicast_leave: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_ue_multicast_leave_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_ue_multicast_leave: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// ENB Measures
// Messages for triggering measurement
//---------------------------------------------------------------------------
void nasrg_set_msg_eNBmeasure_trigger_reply(struct nas_msg_enb_measure_trigger_reply *msgrep, struct nas_msg_enb_measure_trigger *msgreq)
{
//---------------------------------------------------------------------------
struct cx_entity *cx;
int lcr=0; // Temp lcr->mt =0 (should be GC uplink)
cx=nasrg_COMMON_search_cx(lcr);
if (msgreq->cell_id != cx->cellid)
printk("\nERROR : invalid cell_id received\n\n");
if (nasrg_ASCTL_DC_send_eNBmeasurement_req(cx)>0)
msgrep->status = 0;
else
msgrep->status = NAS_ERROR_NOTCORRECTVALUE ;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_eNBmeasure_trigger_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_enb_measure_trigger msgreq;
struct nas_msg_enb_measure_trigger_reply msgrep;
printk("nasrg_ioCTL_eNBmeasure_trigger_request: Measures triggered\n");
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) {
printk("nasrg_ioCTL_eNBmeasure_trigger_request: copy_from_user failure\n");
return -EFAULT;
}
nasrg_set_msg_eNBmeasure_trigger_reply(&msgrep, &msgreq);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_eNBmeasure_trigger_request: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// ENb Measurement
// Messages for Measurement retrieval
//---------------------------------------------------------------------------
void nasrg_set_msg_eNBmeasure_retrieve_reply(struct nas_msg_enb_measure_retrieve *msgrep)
{
//---------------------------------------------------------------------------
int i;
msgrep->cell_id = gpriv->measured_cell_id;
msgrep->num_UEs = gpriv->num_UEs;
for (i=0; i<gpriv-> num_UEs; i++) {
msgrep->measures[i].rlcBufferOccupancy = gpriv->rlcBufferOccupancy[i];
msgrep->measures[i].scheduledPRB = gpriv->scheduledPRB[i];
msgrep->measures[i].totalDataVolume = gpriv->totalDataVolume[i];
//clean variables
gpriv->rlcBufferOccupancy[i] = 0;
gpriv->scheduledPRB[i] = 0;
gpriv->totalDataVolume[i] = 0;
}
msgrep->totalNumPRBs = gpriv->totalNumPRBs;
//clean variable
gpriv->totalNumPRBs = 0;
}
//---------------------------------------------------------------------------
int nasrg_ioCTL_eNBmeasure_retrieve_request(struct nas_ioctl *gifr)
{
//---------------------------------------------------------------------------
struct nas_msg_enb_measure_retrieve msgrep;
printk("nasrg_ioCTL_eNBmeasure_retrieve_request: Measurement requested\n");
nasrg_set_msg_eNBmeasure_retrieve_reply(&msgrep);
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) {
printk("nasrg_ioCTL_eNBmeasure_retrieve_request: copy_to_user failure\n");
return -EFAULT;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IOCTL command
//---------------------------------------------------------------------------
int nasrg_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
//---------------------------------------------------------------------------
struct nas_ioctl *gifr;
int r;
printk("nasrg_CTL_ioctl: begin\n");
spin_lock(&gpriv->lock);
switch(cmd) {
case NASRG_IOCTL_RAL:
gifr=(struct nas_ioctl *)ifr;
switch(gifr->type) {
case NAS_MSG_STATISTIC_REQUEST:
r=nasrg_ioCTL_statistic_request(gifr);
break;
case NAS_MSG_CX_ESTABLISHMENT_REQUEST:
r=nasrg_ioCTL_cx_establishment_request(gifr);
break;
case NAS_MSG_CX_RELEASE_REQUEST:
r=nasrg_ioCTL_cx_release_request(gifr);
break;
case NAS_MSG_CX_LIST_REQUEST:
r=nasrg_ioCTL_cx_list_request(gifr);
break;
case NAS_MSG_RB_ESTABLISHMENT_REQUEST:
r=nasrg_ioCTL_rb_establishment_request(gifr);
break;
case NAS_MSG_RB_RELEASE_REQUEST:
r=nasrg_ioCTL_rb_release_request(gifr);
break;
case NAS_MSG_RB_LIST_REQUEST:
r=nasrg_ioCTL_rb_list_request(gifr);
break;
case NAS_MSG_CLASS_ADD_REQUEST:
r=nasrg_ioCTL_class_add_request(gifr);
break;
case NAS_MSG_CLASS_LIST_REQUEST:
r=nasrg_ioCTL_class_list_request(gifr);
break;
case NAS_MSG_CLASS_DEL_REQUEST:
r=nasrg_ioCTL_class_del_request(gifr);
break;
case NAS_RG_MSG_MT_MCAST_JOIN:
r=nasrg_ioCTL_ue_multicast_join_request(gifr);
break;
case NAS_RG_MSG_MT_MCAST_LEAVE:
r=nasrg_ioCTL_ue_multicast_leave_request(gifr);
break;
case NAS_MSG_ENB_MEAS_TRIGGER:
r=nasrg_ioCTL_eNBmeasure_trigger_request(gifr);
break;
case NAS_MSG_ENB_MEAS_RETRIEVE:
r=nasrg_ioCTL_eNBmeasure_retrieve_request(gifr);
break;
default:
printk("nasrg_CTL_ioctl: unkwon request type, type=%x\n", gifr->type);
r=-EFAULT;
}
break;
default:
printk("nasrg_CTL_ioctl: Unknown ioctl command, cmd=%x\n", cmd);
r=-EFAULT;
}
spin_unlock(&gpriv->lock);
printk("nasrg_CTL_ioctl: end\n");
return r;
}
//---------------------------------------------------------------------------
void nasrg_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
printk("nasrg_CTL_send - void \n");
}
@@ -1,251 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_iocontrol.h
* \brief I/O control constnats and structures for upper layers of driver for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef NASRGD_CTL_H
#define NASRGD_CTL_H
#include <asm/byteorder.h>
#include <asm/types.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#define NAS_MSG_MAXLEN 1100
// type of CTL message
#define NAS_MSG_STATISTIC_REQUEST 1
#define NAS_MSG_STATISTIC_REPLY 2
#define NAS_MSG_ECHO_REQUEST 3
#define NAS_MSG_ECHO_REPLY 4
#define NAS_MSG_CX_ESTABLISHMENT_REQUEST 5
#define NAS_MSG_CX_ESTABLISHMENT_REPLY 6
#define NAS_MSG_CX_RELEASE_REQUEST 7
#define NAS_MSG_CX_RELEASE_REPLY 8
#define NAS_MSG_CX_LIST_REQUEST 9
#define NAS_MSG_CX_LIST_REPLY 10
#define NAS_MSG_RB_ESTABLISHMENT_REQUEST 11
#define NAS_MSG_RB_ESTABLISHMENT_REPLY 12
#define NAS_MSG_RB_RELEASE_REQUEST 13
#define NAS_MSG_RB_RELEASE_REPLY 14
#define NAS_MSG_RB_LIST_REQUEST 15
#define NAS_MSG_RB_LIST_REPLY 16
#define NAS_MSG_CLASS_ADD_REQUEST 17
#define NAS_MSG_CLASS_ADD_REPLY 18
#define NAS_MSG_CLASS_DEL_REQUEST 19
#define NAS_MSG_CLASS_DEL_REPLY 20
#define NAS_MSG_CLASS_LIST_REQUEST 21
#define NAS_MSG_CLASS_LIST_REPLY 22
#define NAS_MSG_NEIGHBOUR_REQUEST 23
#define NAS_MSG_NEIGHBOUR_REPLY 24
//MBMS
#define NAS_RG_MSG_MT_MCAST_JOIN 30
#define NAS_RG_MSG_MT_MCAST_LEAVE 31
#define NAS_RG_MSG_MT_MCAST_REPLY 32
// ENB MEASURES (MEDIEVAL DEMO 3)
#define NAS_MSG_ENB_MEAS_TRIGGER 33
#define NAS_MSG_ENB_MEAS_RETRIEVE 34
// Max number of entry of a message list
#define NAS_LIST_CX_MAX 32
#define NAS_LIST_RB_MAX 32
#define NAS_LIST_CLASS_MAX 32
typedef uint16_t nasMsgType_t;
struct nas_ioctl {
char name[IFNAMSIZ];
nasMsgType_t type;
char *msg;
};
//****
struct nas_msg_statistic_reply {
uint32_t rx_packets;
uint32_t tx_packets;
uint32_t rx_bytes;
uint32_t tx_bytes;
uint32_t rx_errors;
uint32_t tx_errors;
uint32_t rx_dropped;
uint32_t tx_dropped;
};
//****
struct nas_msg_cx_list_reply {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t state;
nasCellID_t cellid; // cell identification
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
uint16_t num_rb;
uint16_t nsclassifier;
};
//****
struct nas_msg_cx_establishment_reply {
int status;
};
struct nas_msg_cx_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasCellID_t cellid; // Cell identification
};
//****
struct nas_msg_cx_release_reply {
int status;
};
struct nas_msg_cx_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
//****
struct nas_msg_rb_list_reply {
nasRadioBearerId_t rab_id;
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
uint8_t state;
uint32_t cnxid;
};
struct nas_msg_rb_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
};
//****
struct nas_msg_rb_establishment_reply {
int status;
uint32_t cnxid;
};
struct nas_msg_rb_establishment_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
nasQoSTrafficClass_t qos;
uint16_t dscp_ul;
uint16_t dscp_dl;
uint16_t mcast_flag;
uint8_t mcast_group[16];
uint32_t cnxid;
};
//****
struct nas_msg_rb_release_reply {
int status;
uint32_t cnxid;
};
struct nas_msg_rb_release_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
uint16_t mcast_flag;
uint32_t cnxid;
};
//****
struct nas_msg_class_add_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
nasRadioBearerId_t rab_id;
uint8_t dir; // direction (send or receive)
uint8_t dscp; // codepoint
uint8_t fct;
uint16_t classref;
uint8_t version;
union {
struct in6_addr ipv6;
uint32_t ipv4;
} saddr; // IP source address
uint8_t splen; // prefix length
union {
struct in6_addr ipv6;
uint32_t ipv4;
} daddr; // IP destination address
uint8_t dplen; // prefix length
uint8_t protocol; // high layer protocol type
uint16_t sport; // source port
uint16_t dport; // destination port
};
struct nas_msg_class_add_reply {
int status;
};
//****
struct nas_msg_class_del_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t dir; // direction (send or receive)
uint8_t dscp; // codepoint
uint16_t classref;
};
struct nas_msg_class_del_reply {
int status;
};
//****
#define nas_msg_class_list_reply nas_msg_class_add_request
struct nas_msg_class_list_request {
nasLocalConnectionRef_t lcr; // Local Connection reference
uint8_t dir;
uint8_t dscp;
};
//****
struct nas_msg_neighbour_cell_list_reply {
nasCellID_t cellid; // cell identification
uint32_t iid6[4]; // IPv6 address of access router
};
//MBMS
//****
struct nas_msg_mt_mcast_join {
nasLocalConnectionRef_t ue_id;
uint32_t cnxid;
nasRadioBearerId_t rab_id;
};
struct nas_msg_mt_mcast_leave {
nasLocalConnectionRef_t ue_id;
uint32_t cnxid;
nasRadioBearerId_t rab_id;
};
struct nas_msg_mt_mcast_reply {
nasLocalConnectionRef_t ue_id;
uint32_t cnxid;
int result;
};
//****
//MEDIEVAL DEMO 3
//****
struct nas_msg_enb_measure_trigger {
nasCellID_t cell_id;
};
struct nas_msg_enb_measure_trigger_reply {
int status;
};
struct nas_msg_enb_measure_retrieve {
nasCellID_t cell_id;
nasNumConnUEs_t num_UEs;
nasENbMeasures_t measures[MAX_MEASURE_UE];
nasENbMeasure_t totalNumPRBs;
};
#endif
@@ -1,246 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_netlink.c
* \brief Netlink socket functions for OpenAirInterface CELLULAR version - MT
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
//#include <linux/config.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include "nasrg_variables.h"
#include "nasrg_proto.h"
static struct sock *nas_nl_sk = NULL;
static struct sock *nas_rrcnl_sk = NULL;
//static int exit_netlink_thread=0;
static DEFINE_MUTEX(nasrg_mutex);
// This can also be implemented using thread to get the data from PDCP without blocking.
//---------------------------------------------------------------------------
// Function for transfer with PDCP (from NASLITE)
static void nasrg_nl_data_ready (struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct nlmsghdr *nlh = NULL;
// Start debug information
#ifdef NETLINK_DEBUG
printk("nasrg_nl_data_ready - begin \n");
#endif
if (!skb) {
printk("nasrg_nl_data_ready - input parameter skb is NULL \n");
return;
}
// End debug information
#ifdef NETLINK_DEBUG
printk("nasrg_nl_data_ready - Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
nasrg_COMMON_QOS_receive(nlh);
}
//---------------------------------------------------------------------------
// Function for transfer with RRC
static void nasrg_rrcnl_data_ready (struct sk_buff *skb)
{
//---------------------------------------------------------------------------
struct nlmsghdr *nlh = NULL;
char target_sap;
uint8_t cxi;
// Start debug information
#ifdef NAS_DEBUG_RRCNL
printk("nasrg_rrcnl_data_ready - begin \n");
#endif
if (!skb) {
printk("nasrg_rrcnl_data_ready - input parameter skb is NULL \n");
return;
}
// End debug information
nlh = (struct nlmsghdr *)skb->data;
//pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh);
//nasrg_TOOL_print_buffer((char *)NLMSG_DATA(nlh), 48);
target_sap = ((char*)NLMSG_DATA(nlh))[0];
#ifdef NAS_DEBUG_RRCNL
printk("nasrg_rrcnl_data_ready - Received on socket from RRC, SAP %d\n", target_sap);
#endif //NAS_DEBUG_RRCNL
switch (target_sap) {
case RRC_NAS_DC0_OUT:
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
cxi = 0;
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
break;
case RRC_NAS_DC1_OUT:
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
cxi = 1;
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
break;
case RRC_NAS_DC2_OUT:
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
cxi = 2;
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
break;
default:
printk("nasrg_rrcnl_data_ready - Invalid SAP value received\n");
}
}
//---------------------------------------------------------------------------
int nasrg_netlink_init(void)
{
//---------------------------------------------------------------------------
printk("nasrg_netlink_init - begin \n");
nas_nl_sk = netlink_kernel_create(&init_net,OAI_IP_DRIVER_NETLINK_ID, 0, nasrg_nl_data_ready,
&nasrg_mutex, // NULL
THIS_MODULE);
if (!nas_nl_sk) {
printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket\n");
// TEMP printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket %d\n", errno);
return(-1);
}
nas_rrcnl_sk = netlink_kernel_create(&init_net,NAS_RRCNL_ID, 0, nasrg_rrcnl_data_ready,
&nasrg_mutex, // NULL
THIS_MODULE);
if (!nas_rrcnl_sk) {
printk("nasrg_rrcnl_init - netlink_kernel_create failed for RRC socket\n");
return(-1);
}
return(0);
}
//---------------------------------------------------------------------------
void nasrg_netlink_release(void)
{
//---------------------------------------------------------------------------
printk("nasrg_netlink_release - begin \n");
//exit_netlink_thread=1;
printk("nasrg_netlink_release - Releasing netlink sockets\n");
if(nas_nl_sk) {
netlink_kernel_release(nas_nl_sk);
}
if(nas_rrcnl_sk) {
netlink_kernel_release(nas_rrcnl_sk);
}
}
//---------------------------------------------------------------------------
int nasrg_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination)
{
//---------------------------------------------------------------------------
struct sk_buff *nl_skb;
struct nlmsghdr *nlh;
int status;
// Start debug information
#ifdef NETLINK_DEBUG
printk("nasrg_netlink_send - begin \n");
#endif
if (!data_buffer) {
printk("nasrg_netlink_send - ERROR - input parameter data is NULL \n");
return(0);
}
if (!nas_nl_sk || !nas_rrcnl_sk) {
printk("nasrg_netlink_send - ERROR - socket is NULL\n");
return(0);
}
// End debug information
nl_skb = alloc_skb(NLMSG_SPACE(data_length),GFP_ATOMIC);
if (!nl_skb) {
printk("nasrg_netlink_send - ERROR - could not allocate skbuffer\n");
return(0);
}
nlh = (struct nlmsghdr *)nl_skb->data;
// printk("nasrg_netlink_send Sending %d bytes (%d)\n",data_length,NLMSG_SPACE(data_length));
skb_put(nl_skb, NLMSG_SPACE(data_length));
memcpy(NLMSG_DATA(nlh), data_buffer, data_length);
nlh->nlmsg_len = NLMSG_SPACE(data_length);
nlh->nlmsg_pid = 0; /* from kernel */
NETLINK_CB(nl_skb).pid = 0;
// destination 0 = PDCP, 1 = RRC
if (destination== NASNL_DEST_PDCP) {
#ifdef NETLINK_DEBUG
printk("nasrg_netlink_send - Sending to PDCP - nl_skb %p, nl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_nl_sk, nlh, nlh->nlmsg_len);
#ifdef NAS_DEBUG_SEND_DETAIL
nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),48);
#endif
#endif //DEBUG_NETLINK
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
} else {
#ifdef NAS_DEBUG_RRCNL
printk("nasrg_netlink_send - Sending to RRC - nl_skb %p, nas_rrcnl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_rrcnl_sk, nlh, nlh->nlmsg_len);
nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),data_length);
#endif //NAS_DEBUG_RRCNL
status = netlink_unicast(nas_rrcnl_sk, nl_skb, NL_DEST_RRC_PID, MSG_DONTWAIT);
}
if (status < 0) {
printk("nasrg_netlink_send - SEND status is %d\n",status);
return(0);
} else {
#ifdef NETLINK_DEBUG
printk("nasrg_netlink_send - SEND status is %d, data_length %d\n",status, data_length);
#endif
return data_length;
}
}
@@ -1,135 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_proto.h
* \brief Function prototypes for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASRGD_PROTO_H
#define _NASRGD_PROTO_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
// #include "rrc_nas_primitives.h"
// #include "protocol_vars_extern.h"
// #include "as_sap.h"
// #include "rrc_qos.h"
// #include "rrc_sap.h"
// nasrg_netlink.c
void nasrg_netlink_release(void);
int nasrg_netlink_init(void);
int nasrg_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination);
// nasrg_common.c
//void nasrg_COMMON_receive(uint16_t hlen, uint16_t dlength, int sap);
void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
void nasrg_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
void nasrg_COMMON_QOS_send_test_netlink(struct sk_buff *skb);
void nasrg_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
#ifndef PDCP_USE_NETLINK
void nasrg_COMMON_QOS_receive(struct cx_entity *cx);
#else
void nasrg_COMMON_QOS_receive(struct nlmsghdr *nlh);
#endif
struct rb_entity *nasrg_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rabi, nasQoSTrafficClass_t qos);
struct rb_entity *nasrg_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rabi);
struct cx_entity *nasrg_COMMON_search_cx(nasLocalConnectionRef_t lcr);
void nasrg_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp);
void nasrg_COMMON_flush_rb(struct cx_entity *cx);
//nasrg_ascontrol.c
void nasrg_ASCTL_init(void);
void nasrg_ASCTL_timer(unsigned long data);
void nasrg_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
//int nasrg_ASCTL_DC_receive(struct cx_entity *cx);
int nasrg_ASCTL_DC_receive(struct cx_entity *cx, char *buffer);
//
int nasrg_ASCTL_DC_send_cx_establish_confirm(struct cx_entity *cx, uint8_t response);
int nasrg_ASCTL_DC_send_rb_establish_request(struct cx_entity *cx, struct rb_entity *rb);
int nasrg_ASCTL_DC_send_rb_release_request(struct cx_entity *cx, struct rb_entity *rb);
int nasrg_ASCTL_GC_send_mbms_bearer_establish_req(int mbms_ix );
int nasrg_ASCTL_GC_send_mbms_bearer_release_req(int mbms_ix);
int nasrg_ASCTL_DC_send_mbms_ue_notify_req(struct cx_entity *cx);
int nasrg_ASCTL_DC_send_eNBmeasurement_req(struct cx_entity *cx);
void nasrg_ASCTL_start_default_mbms_service(void);
// nasrg_iocontrol.c
void nasrg_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
int nasrg_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
// nasrg_classifier.c
void nasrg_CLASS_send(struct sk_buff *skb);
struct classifier_entity *nasrg_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref);
struct classifier_entity *nasrg_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref);
struct classifier_entity *nasrg_CLASS_add_mbmsclassifier(int mbms_ix, uint16_t classref);
void nasrg_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref);
void nasrg_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref);
void nasrg_CLASS_del_mbmsclassifier(int mbms_ix, uint16_t classref);
void nasrg_CLASS_flush_sclassifier(struct cx_entity *cx);
void nasrg_CLASS_flush_rclassifier(void);
void nasrg_CLASS_flush_mbmsclassifier(void);
// nasrg_tool.c
uint8_t nasrg_TOOL_invfct(struct classifier_entity *gc);
void nasrg_TOOL_fct(struct classifier_entity *gc, uint8_t fct);
void nasrg_TOOL_imei2iid(uint8_t *imei, uint8_t *iid);
void nasrg_TOOL_RGimei2iid(uint8_t *imei, uint8_t *iid);
uint8_t nasrg_TOOL_get_dscp6(struct ipv6hdr *iph);
uint8_t nasrg_TOOL_get_dscp4(struct iphdr *iph);
uint8_t *nasrg_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol);
uint8_t *nasrg_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol);
char *nasrg_TOOL_get_udpmsg(struct udphdr *udph);
uint16_t nasrg_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, uint8_t proto, uint32_t udplen, void *data);
int nasrg_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, uint8_t plen);
int nasrg_TOOL_network4(uint32_t *addr, uint32_t *prefix, uint8_t plen);
void nasrg_TOOL_pk_icmp6(struct icmp6hdr *icmph);
void nasrg_TOOL_pk_all(struct sk_buff *skb);
void nasrg_TOOL_pk_ipv6(struct ipv6hdr *iph);
void nasrg_TOOL_print_state(uint8_t state);
void nasrg_TOOL_print_buffer(unsigned char * buffer,int length);
void nasrg_TOOL_print_rb_entity(struct rb_entity *rb);
void nasrg_TOOL_print_classifier(struct classifier_entity *gc);
#endif
@@ -1,77 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasmt_sap.h
* \brief SAP constants for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASRGD_SAP_H
#define _NASRGD_SAP_H
// RT-FIFO identifiers ** must be identical to Access Stratum as_sap.h and rrc_sap.h
#define RRC_DEVICE_GC RRC_SAPI_RG_GCSAP
#define RRC_DEVICE_NT RRC_SAPI_RG_NTSAP
#define RRC_DEVICE_DC_INPUT0 RRC_SAPI_RG_DCSAP0_IN
#define RRC_DEVICE_DC_INPUT1 RRC_SAPI_RG_DCSAP1_IN
#define RRC_DEVICE_DC_OUTPUT0 RRC_SAPI_RG_DCSAP0_OUT
#define RRC_DEVICE_DC_OUTPUT1 RRC_SAPI_RG_DCSAP1_OUT
//
//#define QOS_DEVICE_CONVERSATIONAL_INPUT QOS_SAPI_CONVERSATIONAL_INPUT_RG
//#define QOS_DEVICE_CONVERSATIONAL_OUTPUT QOS_SAPI_CONVERSATIONAL_OUTPUT_RG
#define PDCP2PDCP_USE_RT_FIFO 21
#define NAS2PDCP_FIFO 22
//FIFO indexes in control blocks
#define NAS_DC_INPUT_SAPI 0
#define NAS_DC_OUTPUT_SAPI 1
#define NAS_SAPI_CX_MAX 2
#define NAS_GC_SAPI 0
#define NAS_NT_SAPI 1
#define NAS_DRB_INPUT_SAPI 2 //NAS_CO_INPUT_SAPI
#define NAS_DRB_OUTPUT_SAPI 3 //NAS_CO_OUTPUT_SAPI
#define NAS_SAPI_MAX 4
//#define NAS_QOS_CONVERSATIONAL UMTS_TRAFFIC_CONVERSATIONAL
//
/* Defined in RRC
#define RRC_NAS_GC_IN 0
#define RRC_NAS_GC_OUT 1
#define RRC_NAS_NT_IN 2
#define RRC_NAS_NT_OUT 3
#define RRC_NAS_DC0_IN 4
#define RRC_NAS_DC0_OUT 5
#define RRC_NAS_DC1_IN 6
#define RRC_NAS_DC1_OUT 7
#define RRC_NAS_DC2_IN 8
#define RRC_NAS_DC2_OUT 9
*/
#endif
@@ -1,478 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nasrg_variables.h"
#include "nasrg_proto.h"
//---------------------------------------------------------------------------
//
void nasrg_TOOL_fct(struct classifier_entity *gc, uint8_t fct)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_fct - begin \n");
#endif
if (gc==NULL) {
printk("nasrg_TOOL_fct - input parameter gc is NULL \n");
return;
}
// End debug information
switch(fct) {
case NAS_FCT_QOS_SEND:
gc->fct=nasrg_COMMON_QOS_send;
break;
case NAS_FCT_CTL_SEND:
gc->fct=nasrg_CTL_send;
break;
case NAS_FCT_DC_SEND:
gc->fct=nasrg_ASCTL_DC_send_sig_data_request;
break;
case NAS_FCT_DEL_SEND:
gc->fct=nasrg_COMMON_del_send;
break;
default:
gc->fct=nasrg_COMMON_del_send;
}
}
//---------------------------------------------------------------------------
uint8_t nasrg_TOOL_invfct(struct classifier_entity *gc)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_invfct - begin \n");
#endif
if (gc==NULL) {
printk("nasrg_TOOL_invfct - input parameter gc is NULL \n");
return 0;
}
// End debug information
if (gc->fct==nasrg_COMMON_QOS_send)
return NAS_FCT_QOS_SEND;
if (gc->fct==nasrg_CTL_send)
return NAS_FCT_CTL_SEND;
if (gc->fct==nasrg_COMMON_del_send)
return NAS_FCT_DEL_SEND;
if (gc->fct==nasrg_ASCTL_DC_send_sig_data_request)
return NAS_FCT_DC_SEND;
return 0;
}
//---------------------------------------------------------------------------
uint8_t nasrg_TOOL_get_dscp6(struct ipv6hdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_get_dscp6 - begin \n");
#endif
if (iph==NULL) {
printk("nasrg_TOOL_get_dscp6 - input parameter iph is NULL \n");
return 0;
}
// End debug information
// return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>22; //Yan
return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>20;
}
//---------------------------------------------------------------------------
uint8_t nasrg_TOOL_get_dscp4(struct iphdr *iph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_get_dscp4 - begin \n");
#endif
if (iph==NULL) {
printk("nasrg_TOOL_get_dscp4 - input parameter iph is NULL \n");
return 0;
}
// End debug information
return ((iph->tos)>>5)<<3;
}
//---------------------------------------------------------------------------
uint8_t *nasrg_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
uint16_t size;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_get_protocol6 - begin \n");
#endif
if (iph==NULL) {
printk("nasrg_TOOL_get_protocol6 - input parameter iph is NULL \n");
return NULL;
}
if (protocol==NULL) {
printk("nasrg_TOOL_get_protocol6 - input parameter protocol is NULL \n");
return NULL;
}
// End debug information
*protocol=iph->nexthdr;
size=NAS_IPV6_SIZE;
while (1) {
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
return (uint8_t *)((uint8_t *)iph+size);
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]*8+8;
break;
case IPPROTO_FRAGMENT:
*protocol=((uint8_t *)iph+size)[0];
size+=((uint8_t *)iph+size)[1]+8;
break;
case IPPROTO_NONE:
case IPPROTO_AH:
case IPPROTO_ESP:
default:
return NULL;
}
}
}
//---------------------------------------------------------------------------
uint8_t *nasrg_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_get_protocol4 - begin \n");
#endif
if (iph==NULL) {
printk("nasrg_TOOL_get_protocol4 - input parameter iph is NULL \n");
return NULL;
}
if (protocol==NULL) {
printk("nasrg_TOOL_get_protocol4 - input parameter protocol is NULL \n");
return NULL;
}
// End debug information
*protocol=iph->protocol;
switch(*protocol) {
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
return (uint8_t *)((uint8_t *)iph+iph->tot_len);
default:
return NULL;
}
}
//---------------------------------------------------------------------------
// Convert the IMEI to iid
void nasrg_TOOL_imei2iid(uint8_t *imei, uint8_t *iid)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_imei2iid - begin \n");
#endif
if (imei==NULL) {
printk("nasrg_TOOL_imei2iid - input parameter imei is NULL \n");
return;
}
if (iid==NULL) {
printk("nasrg_TOOL_imei2iid - input parameter iid is NULL \n");
return;
}
// End debug information
memset(iid, 0, NAS_ADDR_LEN);
iid[0] = 0x03;
#ifdef NAS_DRIVER_TYPE_ETHERNET
iid[0] = 0x02;
#endif
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 16*imei[4]+imei[5];
iid[4] = 16*imei[6]+imei[7];
#ifdef NAS_DRIVER_TYPE_ETHERNET
iid[3] = 0xff;
iid[4] = 0xfe;
#endif
iid[5] = 16*imei[8]+imei[9];
iid[6] = 16*imei[10]+imei[11];
iid[7] = 16*imei[12]+imei[13];
}
//---------------------------------------------------------------------------
// Convert the RG IMEI to iid
void nasrg_TOOL_RGimei2iid(uint8_t *imei, uint8_t *iid)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_RGimei2iid - begin \n");
#endif
if (!imei || !iid) {
printk("nasrg_TOOL_RGimei2iid - input parameter imei or iid is NULL \n");
return;
}
// End debug information
memset(iid, 0, NAS_ADDR_LEN);
iid[0] = 0x00; // to be compatible between link local and global
iid[1] = 16*imei[0]+imei[1];
iid[2] = 16*imei[2]+imei[3];
iid[3] = 16*imei[4]+imei[5];
iid[4] = 16*imei[6]+imei[7];
iid[5] = 16*imei[8]+imei[9];
iid[6] = 16*imei[10]+imei[11];
iid[7] = 16*imei[12]+imei[13];
}
//---------------------------------------------------------------------------
void nasrg_TOOL_pk_icmp6(struct icmp6hdr *icmph)
{
//---------------------------------------------------------------------------
// Start debug information
#ifdef GRAAL_DEBUG_TOOL
printk("nasrg_TOOL_pk_icmp6 - begin \n");
#endif
if (!icmph) {
printk("nasrg_TOOL_pk_icmp6 - input parameter icmph is NULL \n");
return;
}
// End debug information
printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code);
switch(icmph->icmp6_type) {
case ICMPV6_DEST_UNREACH:
printk("Destination unreachable\n");
break;
case ICMPV6_PKT_TOOBIG:
printk("Packet too big\n");
break;
case ICMPV6_TIME_EXCEED:
printk("Time exceeded\n");
break;
case ICMPV6_PARAMPROB:
printk("Parameter problem\n");
break;
case ICMPV6_ECHO_REQUEST:
printk("Echo request\n");
break;
case ICMPV6_ECHO_REPLY:
printk("Echo reply\n");
break;
case ICMPV6_MGM_QUERY:
printk("Multicast listener query\n");
break;
case ICMPV6_MGM_REPORT:
printk("Multicast listener report\n");
break;
case ICMPV6_MGM_REDUCTION:
printk("Multicast listener done\n");
break;
case NDISC_ROUTER_SOLICITATION:
printk("Router solicitation\n");
break;
case NDISC_ROUTER_ADVERTISEMENT:
printk("Router advertisment\n");
break;
case NDISC_NEIGHBOUR_SOLICITATION:
printk("Neighbour solicitation\n");
break;
case NDISC_NEIGHBOUR_ADVERTISEMENT:
printk("Neighbour advertisment\n");
break;
case NDISC_REDIRECT:
printk("redirect message\n");
break;
}
}
//---------------------------------------------------------------------------
void nasrg_TOOL_print_state(uint8_t state)
{
//---------------------------------------------------------------------------
switch(state) {
case NAS_IDLE:
printk("NAS_IDLE\n");
return;
case NAS_CX_FACH:
printk("NAS_CX_FACH\n");
return;
case NAS_CX_DCH:
printk("NAS_CX_DCH\n");
return;
case NAS_CX_RECEIVED:
printk("NAS_CX_RECEIVED\n");
return;
case NAS_CX_CONNECTING:
printk("NAS_CX_CONNECTING\n");
return;
case NAS_CX_RELEASING:
printk("NAS_CX_RELEASING\n");
return;
case NAS_CX_CONNECTING_FAILURE:
printk("NAS_CX_CONNECTING_FAILURE\n");
return;
case NAS_CX_RELEASING_FAILURE:
printk("NAS_CX_RELEASING_FAILURE\n");
return;
case NAS_RB_ESTABLISHING:
printk("NAS_RB_ESTABLISHING\n");
return;
case NAS_RB_RELEASING:
printk("NAS_RB_RELEASING\n");
return;
case NAS_RB_ESTABLISHED:
printk("NAS_RB_ESTABLISHED\n");
return;
default:
printk(" Unknown state\n");
}
}
//-----------------------------------------------------------------------------
// Print the content of a buffer in hexadecimal
void nasrg_TOOL_print_buffer(unsigned char * buffer,int length)
{
//-----------------------------------------------------------------------------
int i;
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_print_buffer - begin \n");
#endif
if (buffer==NULL) {
printk("\n nasrg_TOOL_print_buffer - input parameter buffer is NULL \n");
return;
}
// End debug information
printk("Buffer content: ");
for (i=0; i<length; i++)
printk("-%hx-",buffer[i]);
printk(",\t length %d\n", length);
}
//-----------------------------------------------------------------------------
void nasrg_TOOL_print_rb_entity(struct rb_entity *rb)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_print_rb_entity - begin \n");
#endif
if (rb==NULL) {
printk("\n nasrg_TOOL_print_rb_entity - input parameter rb is NULL \n");
return;
}
// End debug information
printk("\nrb_entity content: rab_id %d, sapi %d, qos %d, dscp %d, \n", rb->rab_id, rb->sapi, rb->qos, rb->dscp);
printk("state %d, retry %d, countimer %d\n",rb->state, rb->retry, rb->countimer);
};
//-----------------------------------------------------------------------------
void nasrg_TOOL_print_classifier(struct classifier_entity *gc)
{
//-----------------------------------------------------------------------------
// Start debug information
#ifdef NAS_DEBUG_TOOL
printk("nasrg_TOOL_print_classifier - begin \n");
#endif
if (gc==NULL) {
printk("\n nasrg_TOOL_print_classifier - input parameter gc is NULL \n");
return;
}
// End debug information
printk("\nClassifier content: classref %d, version %d, splen %d, dplen %d,\n", gc->classref, gc->version, gc->splen, gc->dplen);
printk("protocol %d, sport %d, dport %d, rab_id %d\n", gc->protocol, gc->sport, gc->dport, gc->rab_id);
nasrg_TOOL_print_rb_entity(gc->rb);
};
@@ -1,214 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nasrg_variables.h
* \brief Variable and structure definitions for OpenAirInterface CELLULAR version - RG
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
* \company Eurecom
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
/*******************************************************************************/
#ifndef _NASRGD_VAR_H
#define _NASRGD_VAR_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
//#include <asm/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "rrc_nas_primitives.h"
#include "rrc_qos_classes.h"
#include "rrc_nas_sap.h"
#include "nasrg_constant.h"
#include "nasrg_sap.h"
struct cx_entity;
struct rb_entity {
// uint16_t default_rab;
uint32_t cnxid;
nasRadioBearerId_t rab_id; //ue_rbId
nasRadioBearerId_t rg_rbId;
nasRadioBearerId_t mbms_rbId;
nasSapId_t sapi;
nasQoSTrafficClass_t qos;
nasQoSTrafficClass_t RadioQosClass;
nasIPdscp_t dscp; //this is DL dscp
nasIPdscp_t dscp_ul;
uint8_t state;
uint8_t result;
uint8_t retry;
uint32_t countimer;
//for MBMS
uint16_t serviceId;
uint16_t sessionId;
uint16_t duration;
uint8_t mcast_address[16];
//
struct rb_entity *next;
};
struct classifier_entity {
uint32_t classref; // classifier identity
uint8_t version; // IP version 4 or 6
union {
struct in6_addr ipv6;
uint32_t ipv4;
} saddr; // IP source address
uint8_t splen; // IP prefix size
union {
struct in6_addr ipv6;
uint32_t ipv4;
} daddr; // IP destination address
uint8_t dplen; // IP prefix size
uint8_t protocol; // layer 4 protocol type (tcp, udp, ...)
uint16_t sport; // source port
uint16_t dport; // destination port
struct rb_entity *rb;
nasRadioBearerId_t rab_id; // RAB identification
void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc);
struct classifier_entity *next;
};
struct cx_entity {
int sap[NAS_SAPI_CX_MAX];
uint8_t state; // state of the connection
nasLocalConnectionRef_t lcr; // Local connection reference
nasCellID_t cellid; // cell identification
uint32_t countimer; // timeout's counter
uint8_t retry; // number of retransmissions
struct classifier_entity *sclassifier[NAS_DSCP_MAX]; // send classifiers table
uint16_t nsclassifier;
uint32_t iid6[2]; // IPv6 interface identification
uint8_t iid4; // IPv4 interface identification
struct rb_entity *rb; // RB entities for RABs
uint16_t num_rb;
// MW - 17/5/05
int ue_id;
int rrc_state;
// MBMS
int requested_joined_services[NASRG_MBMS_SVCES_MAX];
int requested_left_services[NASRG_MBMS_SVCES_MAX];
int joined_services[NASRG_MBMS_SVCES_MAX];
};
//struct mbms_rb_entity{
// uint32_t cnxid;
// nasRadioBearerId_t mbms_rbId;
// nasSapId_t sapi;
// nasQoSTrafficClass_t qos;
// nasQoSTrafficClass_t RadioQosClass;
// uint8_t state;
// uint8_t result;
// uint8_t retry;
// uint32_t countimer;
//
// uint16_t serviceId;
// uint16_t sessionId;
// uint16_t duration;
//};
//
struct nas_priv {
int irq;
int rx_flags;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
uint8_t retry_limit;
uint32_t timer_establishment;
uint32_t timer_release;
struct cx_entity cx[NAS_CX_MAX];
struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier
int nrclassifier;
uint32_t next_sclassref;
int sap[NAS_SAPI_MAX];
uint8_t xbuffer[NAS_MAX_LENGTH]; // transmission buffer
uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer
// MW - 17/5/05
int broadcast_counter;
int SIB18_counter;
// MBMS
struct rb_entity mbms_rb[NASRG_MBMS_SVCES_MAX];
struct classifier_entity *mbmsclassifier[NASRG_MBMS_SVCES_MAX]; // mbms classifier
int nmbmsclassifier;
uint32_t next_mbmsclassref;
//Added for demo 3 - MW
nasCellID_t measured_cell_id;
uint16_t num_UEs;
uint32_t rlcBufferOccupancy[NAS_CX_MAX];
uint32_t scheduledPRB[NAS_CX_MAX];
uint32_t totalDataVolume[NAS_CX_MAX];
uint32_t totalNumPRBs;
};
struct ipversion {
#if defined(__LITTLE_ENDIAN_BITFIELD)
uint8_t reserved:4,
version:4;
#else
uint8_t version:4,
reserved:4;
#endif
};
typedef struct pdcp_data_req_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_ind_header_t;
//
extern struct nas_priv *gpriv;
extern struct net_device *gdev;
//extern int bytes_wrote;
//extern int bytes_read;
extern uint8_t NAS_RG_IMEI[14];
extern uint8_t NAS_NULL_IMEI[14];
//global variables shared with RRC
extern int *pt_nas_rg_irq;
//extern uint16_t *pt_rg_own_cell_id;
extern uint16_t local_rg_cell_id;
#endif
@@ -1,48 +0,0 @@
# Lines starting with the pound sign are comments.
#
# These things are options that you might need
# to tweak.
# You can modify the below as well, but probably
# won't need to.
#CC = egcs
#UPDIR := $(shell /bin/pwd)
#GRAAL_DIR =$(UPDIR)/..
#RRC_DIR =$(UPDIR)/../../../AS/L3/RRC
CELL_UPDIR := $(shell /bin/pwd)
NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASMT
RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR
EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_MT
CFLAGS = -Wall -g -I$(NAS_DIR) -I$(RRC_DIR)
COMPILE = $(CC) $(CFLAGS) -c
OBJS = netltest.o
EXECUTABLE = netltest
# "all" is the default target. Simply make it point to myprogram.
all: $(EXECUTABLE)
# Define the components of the program, and how to link them together.
# These components are defined as dependencies; that is, they must be
# made up-to-date before the code is linked.
$(EXECUTABLE): $(OBJS)
$(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJS)
# Add any special rules here.
# Specify that all .o files depend on .c files, and indicate how
# the .c files are converted (compiled) to the .o files.
%.o: %.c
$(COMPILE) -o $@ $<
clean:
-rm $(OBJS) $(EXECUTABLE)
Binary file not shown.
@@ -1,213 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
//-----------------------------------------------------------------------------
// For FIFOS / NETLINK interface
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/********************
// RRC definitions
********************/
#include "nasmt_constant.h"
#include "rrc_nas_sap.h"
#include "rrc_constant.h"
//-----------------------------------------------------------------------------
//#define MAX_PAYLOAD 4096 /* this sould cover the max mtu size*/
struct nlmsghdr *rrcnl_nlh;
int rrcnl_sock_fd;
struct sockaddr_nl rrcnl_src_addr, rrcnl_dest_addr;
struct iovec rrcnl_iov;
struct msghdr rrcnl_msg;
//-----------------------------------------------------------------------------
typedef unsigned int sdu_size_t;
typedef unsigned int rb_id_t;
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;
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;
#define OAI_IP_DRIVER_NETLINK_ID 31
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void foo( int sig )
{
//-----------------------------------------------------------------------------
printf("I got cntl-C, closing socket\n");
close(sock_fd);
close(rrcnl_sock_fd);
exit(-1);
}
//-----------------------------------------------------------------------------
int main()
{
//-----------------------------------------------------------------------------
struct sigaction newaction;
int i=0;
int ret;
int len, count;
newaction.sa_handler = foo;
// register cntl-C handler
if ( sigaction( SIGINT, &newaction, NULL ) == -1)
perror("Could not install the new signal handler");
// create both sockets
sock_fd = socket(PF_NETLINK, SOCK_RAW,OAI_IP_DRIVER_NETLINK_ID);
printf("Opened socket with fd %d\n",sock_fd);
ret = fcntl(sock_fd,F_SETFL,O_NONBLOCK);
printf("fcntl returns %d\n",ret);
rrcnl_sock_fd = socket(PF_NETLINK, SOCK_RAW, NAS_RRCNL_ID);
printf("rrc_ue_netlink_init - Opened socket with fd %d\n", rrcnl_sock_fd);
ret = fcntl(rrcnl_sock_fd,F_SETFL,O_NONBLOCK);
printf("rrc_ue_netlink_init - fcntl returns %d\n",ret);
// set src addresses blocks
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 1;//getpid(); /* self pid */
src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
printf("bind returns %d\n",ret);
memset(&rrcnl_src_addr, 0, sizeof(rrcnl_src_addr));
rrcnl_src_addr.nl_family = AF_NETLINK;
rrcnl_src_addr.nl_pid = NL_DEST_RRC_PID;//getpid(); /* self pid */
rrcnl_src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(rrcnl_sock_fd, (struct sockaddr*)&rrcnl_src_addr, sizeof(rrcnl_src_addr));
printf("rrc_ue_netlink_init - bind returns %d\n",ret);
// set dest addresses blocks
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */
memset(&rrcnl_dest_addr, 0, sizeof(rrcnl_dest_addr));
rrcnl_dest_addr.nl_family = AF_NETLINK;
rrcnl_dest_addr.nl_pid = 0; /* For Linux Kernel */
rrcnl_dest_addr.nl_groups = 0; /* unicast */
// set nlh
nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nlh->nlmsg_flags = 0;
rrcnl_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(RRC_NAS_MAX_SIZE));
//memset(rrcnl_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
rrcnl_nlh->nlmsg_len = NLMSG_SPACE(RRC_NAS_MAX_SIZE);
rrcnl_nlh->nlmsg_pid = NL_DEST_RRC_PID;//getpid(); /* self pid */
rrcnl_nlh->nlmsg_flags = 0;
// set iov
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
memset(&msg,0,sizeof(msg));
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
rrcnl_iov.iov_base = (void *)rrcnl_nlh;
rrcnl_iov.iov_len = rrcnl_nlh->nlmsg_len;
memset(&rrcnl_msg,0,sizeof(rrcnl_msg));
rrcnl_msg.msg_name = (void *)&rrcnl_dest_addr;
rrcnl_msg.msg_namelen = sizeof(rrcnl_dest_addr);
rrcnl_msg.msg_iov = &rrcnl_iov;
rrcnl_msg.msg_iovlen = 1;
/* Read message from kernel */
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
/* Read message from kernel */
memset(rrcnl_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
while (1) {
len = recvmsg(sock_fd, &msg, 0);
count = recvmsg(rrcnl_sock_fd, &rrcnl_msg, 0);
if (len<0) {
// exit(-1);
} else {
printf("Received PDCP socket with length %d (nlmsg_len = %d)\n",len,nlh->nlmsg_len);
}
if (count<0) {
// exit(-1);
} else {
printf("Received RRC socket with length %d (nlmsg_len = %d)\n",count,rrcnl_nlh->nlmsg_len);
}
/* usleep(1000);
i=i+1;
if ((i % 100) == 0)
printf("%d\n",i);*/
usleep(50);
i=i+1;
if ((i % 1000) == 0)
printf("%d\n",i);
/*
for (i=0;i<nlh->nlmsg_len - sizeof(struct nlmsghdr);i++) {
printf("%x ",
((unsigned char *)NLMSG_DATA(nlh))[i]);
}
*/
}
/* Close Netlink Socket */
return 0;
}
@@ -1,149 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
typedef unsigned int sdu_size_t;
typedef unsigned int rb_id_t;
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;
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;
void foo( int sig )
{
printf("I got cntl-C, closing socket\n");
close(sock_fd);
exit(-1);
}
#define OAI_IP_DRIVER_NETLINK_ID 31
void main()
{
struct sigaction newaction;
int i=0;
int ret;
int len;
newaction.sa_handler = foo;
if ( sigaction( SIGINT, &newaction, NULL ) == -1)
perror("Could not install the new signal handler");
sock_fd = socket(PF_NETLINK, SOCK_RAW,OAI_IP_DRIVER_NETLINK_ID);
printf("Opened socket with fd %d\n",sock_fd);
ret = fcntl(sock_fd,F_SETFL,O_NONBLOCK);
printf("fcntl returns %d\n",ret);
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 1;//getpid(); /* self pid */
src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(sock_fd, (struct sockaddr*)&src_addr,
sizeof(src_addr));
printf("bind returns %d\n",ret);
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */
nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nlh->nlmsg_flags = 0;
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
memset(&msg,0,sizeof(msg));
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
/* Read message from kernel */
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
while (1) {
len = recvmsg(sock_fd, &msg, 0);
if (len<0) {
// exit(-1);
} else {
printf("Received socket with length %d (nlmsg_len = %d)\n",len,nlh->nlmsg_len);
}
usleep(1000);
i=i+1;
if ((i % 100) == 0)
printf("%d\n",i);
/*
for (i=0;i<nlh->nlmsg_len - sizeof(struct nlmsghdr);i++) {
printf("%x ",
((unsigned char *)NLMSG_DATA(nlh))[i]);
}
*/
}
/* Close Netlink Socket */
}
-157
View File
@@ -1,157 +0,0 @@
---------------------------------
| UMTS-TDD (TD-CDMA) NAS driver |
---------------------------------
1 - COMPILATION
---------------
Pre-Req :
- RTAI installed and running
- IPv6 patched as described below (see 4 - Patching IPv6)
From RHODOS26 directory:
- make nasrg : creates the NAS RG driver (nasrg.ko) and copies it to the RHODOS26/bin directory
- make cleannasrg : deletes all object and temporary files from the nasrg directory
- make nasmt : creates the NAS MT driver (nasmt.ko) and copies it to the RHODOS26/bin directory
- make cleannasmt : deletes all object and temporary files from the nasmt directory
2 - OPERATION - RG side
-----------------------
A1 - Compile the Access Stratum (for IF mode)
Pre-Req : RTAI installed and running
ICC 8.0 installed and running
> make rgif
> make asrguserif
> make rrmumts
A2 - Compile the Access Stratum (for RF mode)
Pre-Req : RTAI installed and running
ICC 8.0 installed and running
> make guimakefiles
> make rgrf
> make asrguserrfa2
> make rrmumts
B - Start the Access Stratum
(as root ) > cd <..>RHODOS26/bin
(first install) > create_rtfifos
(first install) > mknod -m 666 /dev/daq0 c 127 1
(after cleanas) > cp
../src/rrm_umts/congestion_control/resources_manager/rrm_master.properties .
(-- ) > ./start_rtos
(-- ) > ./runrgif [for IF] [or ./runrga2 for RF]
==> to check correct operation:
(as root ) cat /dev/rtf62
(as root ) tail -f /var/log/messages
C - Start the NAS Driver
(as root ) > cd <..>RHODOS26/bin
(-- ) > insmod nasrg.ko
(-- ) > ./access_router.up
D - Stop the NAS Driver and the Access Stratum
(-- ) > ./access_router.down
(-- ) > rmmod nasrg
(-- ) > <CTRL+C> on Acccess stratum window
(-- ) > ./stop_rtos
E - Clean Access Stratum compilation
> make cleanas
3 - OPERATION - MT side
-----------------------
A1 - Compile the Access Stratum (for IF mode)
Pre-Req : RTAI installed and running
ICC 8.0 installed and running
file RHODOS26/src/access_stratum/l1/low/control/mmx.h copied in /usr/include
> make mtif
> make asmtuserif
> make fpgatest
A2 - Compile the Access Stratum (for RF mode)
Pre-Req : RTAI installed and running
ICC 8.0 installed and running
file RHODOS26/src/access_stratum/l1/low/control/mmx.h copied in /usr/include
> make guimakefiles
> make mtrf
> make asmtuserrf
> make fpgatest
B - Start the Access Stratum
(as root ) > cd <..>RHODOS26/bin
(first install) > create_rtfifos
(first install) > mknod -m 666 /dev/daq0 c 127 1
(-- ) > ./start_rtos
(-- ) > ./runrgif [for IF] [or ./runrga2 for RF]
==> to check correct operation:
(as root ) cat /dev/rtf62
(as root ) tail -f /var/log/messages
C - Start the NAS Driver
(as root ) > cd <..>RHODOS26/bin
(-- ) > insmod nasmt.ko
(-- ) > ./mobile_node.up
D - Stop the NAS Driver and the Access Stratum
(-- ) > ./mobile_node.down
(-- ) > rmmod nasmt
(-- ) > <CTRL+C> on Acccess stratum window
(-- ) > ./stop_rtos
E - Clean Access Stratum compilation
> make cleanas
4 - Patching IPv6
-----------------------
For Linux with 2.6.xx kernel version (xx = 10 or 81):
- move RHODOS26/non_access_stratum/driver/src/addrconf.c.26.xx to /usr/src/linux/net/ipv6/addrconf.c
- move RHODOS26/non_access_stratum/driver/src/if_arp.h.26.xx to /usr/src/linux/include/linux/if_arp.h
- recompile IPv6 (inside the kernel or as a module, as usual)
5 - Start the MT connection
-----------------------
You can use either the RAL-UMTS (RAL-CDMA) -- see corresponding documentation --
* OR *
the tool provided with the driver (directory RHODOS26/src/non_access_stratum/driver/mt_tools).
Install the tool, update the Cell_id field if needed and click on the "Attach" button.
@@ -1,13 +0,0 @@
#xterm -hold "tail -f /var/log/messages" &
insmod ./NASMT/nascellmt.ko nas_IMEI=3,5,6,0,1,4,9,1,5,0,0,0,0,0
#insmod ./NASMT/nascellmt.ko
sleep 2
ifconfig oai0 10.0.1.2 netmask 255.255.255.0 broadcast 10.0.1.255
#ifconfig oai0 add 2001:660:382:14:335:600:8014:9150/64
#./bin/mobile_node.up
#sleep 3
#./CTL_TOOL/gioctl cx add 0 5
#xterm -hold -e ./bin/IALdummy &
#sleep 1
#xterm -hold -e ./bin/tdcdma_gui &
#lsmod
@@ -1,17 +0,0 @@
#xterm -hold -e ant -buildfile rrm_umts.xml run &
#sleep 2
insmod ./NASRG/nascellrg.ko
sleep 2
#bin/access_router_noradvd.up
sysctl -w net.ipv6.conf.default.dad_transmits=0
#sysctl -w net.ipv6.conf.all.forwarding=1
#sysctl -w net.ipv4.conf.all.forwarding=1
#ifconfig oai0 192.168.14.100
ifconfig oai0 10.0.1.3 netmask 255.255.255.0 broadcast 10.0.1.255
ifconfig oai0 add 2001:660:382:14::1/64
#ifconfig graal0 192.168.14.100
#ifconfig graal0 add 2001:690:2380:7777::1/64
#ifconfig graal0 add 2001:660:382:14::1/64
#lsmod
@@ -1,17 +0,0 @@
#xterm -hold -e ant -buildfile rrm_umts.xml run &
#sleep 2
insmod ./NASRG/nascellrg.ko
sleep 2
#bin/access_router_noradvd.up
sysctl -w net.ipv6.conf.default.dad_transmits=0
sysctl -w net.ipv6.conf.all.forwarding=1
#sysctl -w net.ipv4.conf.all.forwarding=1
#ifconfig oai0 192.168.14.100
ifconfig oai0 10.0.1.3 netmask 255.255.255.0 broadcast 10.0.1.255
ifconfig oai0 add 2001:660:382:14::1/64
#lsmod
sleep 4s
radvd
@@ -1,5 +0,0 @@
#killall -qw tdcdma_gui
#killall -qw IALdummy
#./bin/mobile_node.down
rmmod -w nascellmt
@@ -1,2 +0,0 @@
ifconfig oai0 down
rmmod -w nascellrg
-6
View File
@@ -1,6 +0,0 @@
NAS_UE_DIR = $(OPENAIR2_TOP)/NAS
NAS_UE_OBJS =
NAS_UE_incl = \
-I$(NAS_UE_DIR)

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