Commit 83b3d708 authored by Navid Nikaein's avatar Navid Nikaein

Merge branch 'x2-ho' of https://gitlab.eurecom.fr/oai/openairinterface5g into x2-ho

Update the itti x2 ho req message
parents b3d758d9 574934f8
......@@ -76,6 +76,8 @@
#ifndef OCP_FRAMEWORK
typedef enum cell_type_e {
CELL_MACRO_ENB,
CELL_MICRO_ENB,
CELL_SMALL_ENB,
CELL_HOME_ENB
} cell_type_t;
......
......@@ -119,21 +119,45 @@ typedef struct x2ap_gummei_s {
uint16_t mme_group_id;
} x2ap_gummei_t;
typedef struct x2ap_lastvisitedcell_info_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
PhysCellId_t target_physCellId;
cell_type_t cell_type;
uint64_t time_UE_StayedInCell;
}x2ap_lastvisitedcell_info_t;
//used for src
typedef struct x2ap_handover_req_s {
int source_rnti; /* TODO: to be fixed/remove */
int source_x2id; /* TODO: to be fixed/remove */
unsigned old_eNB_ue_s1ap_id:24;
PhysCellId_t target_physCellId;
x2ap_gummei_t ue_gummei;
/*UE-ContextInformation */
/* MME UE id */
uint16_t mme_ue_s1ap_id;
PhysCellId_t target_physCellId;
security_capabilities_t security_capabilities;
uint8_t kenb[32]; // keNB or keNB*
x2ap_gummei_t gummei_id;
/*next_hop_chaining_coun */
long int kenb_ncc;
security_capabilities_t security_capabilities;
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
/* list of e_rab setup-ed by RRC layers */
e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB];
x2ap_lastvisitedcell_info_t lastvisitedcell_info;
/* TODO: this parameter has to be removed */
int target_mod_id;
......
......@@ -359,6 +359,15 @@ typedef struct HANDOVER_INFO_UE_s {
uint8_t measFlag;
} HANDOVER_INFO_UE;
typedef struct ue_gummei_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
uint8_t mme_code;
uint16_t mme_group_id;
} ue_gummei_t;
typedef struct eNB_RRC_UE_s {
uint8_t primaryCC_id;
#if defined(Rel10) || defined(Rel14)
......@@ -387,6 +396,9 @@ typedef struct eNB_RRC_UE_s {
#if defined(ENABLE_SECURITY)
/* KeNB as derived from KASME received from EPC */
uint8_t kenb[32];
int8_t kenb_ncc;
uint8_t nh[32];
int8_t nh_ncc;
#endif
/* Used integrity/ciphering algorithms */
CipheringAlgorithm_r12_t ciphering_algorithm;
......@@ -410,6 +422,9 @@ typedef struct eNB_RRC_UE_s {
/* Information from S1AP initial_context_setup_req */
uint32_t eNB_ue_s1ap_id :24;
/* UE GUMMEI */
ue_gummei_t ue_gummei;
security_capabilities_t security_capabilities;
int next_hop_chain_count;
......@@ -600,6 +615,8 @@ typedef struct UE_RRC_INST_s {
#if defined(ENABLE_SECURITY)
/* KeNB as computed from parameters within USIM card */
uint8_t kenb[32];
uint8_t nh[32];
int8_t nh_ncc;
#endif
/* Used integrity/ciphering algorithms */
......
......@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
const uint8_t ho_state
);
int freq_to_arfcn10(int band, unsigned long freq);
void
rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
const protocol_ctxt_t* const ctxt_pP,
......
......@@ -2160,7 +2160,113 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons
PDCP_TRANSMISSION_MODE_CONTROL);
}
typedef enum { BAND_TYPE_FDD, BAND_TYPE_TDD } band_type;
typedef struct {
band_type t;
int band;
unsigned long ul_minfreq, ul_maxfreq;
unsigned long dl_minfreq, dl_maxfreq;
} band_freq;
static band_freq bands[] = {
{ BAND_TYPE_FDD, 1, 1920000000UL, 1980000000UL, 2110000000UL, 2170000000UL },
{ BAND_TYPE_FDD, 2, 1850000000UL, 1910000000UL, 1930000000UL, 1990000000UL },
{ BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL },
{ BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL },
{ BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL },
/* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL },
{ BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL },
{ BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL },
{ BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL },
{ BAND_TYPE_FDD, 10, 1710000000UL, 1770000000UL, 2110000000UL, 2170000000UL },
{ BAND_TYPE_FDD, 11, 1427900000UL, 1447900000UL, 1475900000UL, 1495900000UL },
{ BAND_TYPE_FDD, 12, 699000000UL, 716000000UL, 729000000UL, 746000000UL },
{ BAND_TYPE_FDD, 13, 777000000UL, 787000000UL, 746000000UL, 756000000UL },
{ BAND_TYPE_FDD, 14, 788000000UL, 798000000UL, 758000000UL, 768000000UL },
{ BAND_TYPE_FDD, 17, 704000000UL, 716000000UL, 734000000UL, 746000000UL },
{ BAND_TYPE_FDD, 18, 815000000UL, 830000000UL, 860000000UL, 875000000UL },
{ BAND_TYPE_FDD, 19, 830000000UL, 845000000UL, 875000000UL, 890000000UL },
{ BAND_TYPE_FDD, 20, 832000000UL, 862000000UL, 791000000UL, 821000000UL },
{ BAND_TYPE_FDD, 21, 1447900000UL, 1462900000UL, 1495900000UL, 1510900000UL },
{ BAND_TYPE_FDD, 22, 3410000000UL, 3490000000UL, 3510000000UL, 3590000000UL },
{ BAND_TYPE_FDD, 23, 2000000000UL, 2020000000UL, 2180000000UL, 2200000000UL },
{ BAND_TYPE_FDD, 24, 1626500000UL, 1660500000UL, 1525000000UL, 1559000000UL },
{ BAND_TYPE_FDD, 25, 1850000000UL, 1915000000UL, 1930000000UL, 1995000000UL },
{ BAND_TYPE_TDD, 33, 1900000000UL, 1920000000UL, 1900000000UL, 1920000000UL },
{ BAND_TYPE_TDD, 34, 2010000000UL, 2025000000UL, 2010000000UL, 2025000000UL },
{ BAND_TYPE_TDD, 35, 1850000000UL, 1910000000UL, 1850000000UL, 1910000000UL },
{ BAND_TYPE_TDD, 36, 1930000000UL, 1990000000UL, 1930000000UL, 1990000000UL },
{ BAND_TYPE_TDD, 37, 1910000000UL, 1930000000UL, 1910000000UL, 1930000000UL },
{ BAND_TYPE_TDD, 38, 2570000000UL, 2620000000UL, 2570000000UL, 2620000000UL },
{ BAND_TYPE_TDD, 39, 1880000000UL, 1920000000UL, 1880000000UL, 1920000000UL },
{ BAND_TYPE_TDD, 40, 2300000000UL, 2400000000UL, 2300000000UL, 2400000000UL },
{ BAND_TYPE_TDD, 41, 2496000000UL, 2690000000UL, 2496000000UL, 2690000000UL },
{ BAND_TYPE_TDD, 42, 3400000000UL, 3600000000UL, 3400000000UL, 3600000000UL },
{ BAND_TYPE_TDD, 43, 3600000000UL, 3800000000UL, 3600000000UL, 3800000000UL },
};
typedef struct {
int band;
unsigned long dl_flow;
int dl_off;
int dl_offmin, dl_offmax;
unsigned long ul_flow;
int ul_off;
int ul_offmin, ul_offmax;
} earfcn;
static earfcn earfcn_table[] = {
{ 1, 2110000000UL, 0, 0, 599, 1920000000UL, 18000, 18000, 18599 },
{ 2, 1930000000UL, 600, 600, 1199, 1850000000UL, 18600, 18600, 19199 },
{ 3, 1805000000UL, 1200, 1200, 1949, 1710000000UL, 19200, 19200, 19949 },
{ 4, 2110000000UL, 1950, 1950, 2399, 1710000000UL, 19950, 19950, 20399 },
{ 5, 869000000UL, 2400, 2400, 2649, 824000000UL, 20400, 20400, 20649 },
{ 6, 875000000UL, 2650, 2650, 2749, 830000000UL, 20650, 20650, 20749 },
{ 7, 2620000000UL, 2750, 2750, 3449, 2500000000UL, 20750, 20750, 21449 },
{ 8, 925000000UL, 3450, 3450, 3799, 880000000UL, 21450, 21450, 21799 },
{ 9, 1844900000UL, 3800, 3800, 4149, 1749900000UL, 21800, 21800, 22149 },
{ 10, 2110000000UL, 4150, 4150, 4749, 1710000000UL, 22150, 22150, 22749 },
{ 11, 1475900000UL, 4750, 4750, 4949, 1427900000UL, 22750, 22750, 22949 },
{ 12, 729000000UL, 5010, 5010, 5179, 699000000UL, 23010, 23010, 23179 },
{ 13, 746000000UL, 5180, 5180, 5279, 777000000UL, 23180, 23180, 23279 },
{ 14, 758000000UL, 5280, 5280, 5379, 788000000UL, 23280, 23280, 23379 },
{ 17, 734000000UL, 5730, 5730, 5849, 704000000UL, 23730, 23730, 23849 },
{ 18, 860000000UL, 5850, 5850, 5999, 815000000UL, 23850, 23850, 23999 },
{ 19, 875000000UL, 6000, 6000, 6149, 830000000UL, 24000, 24000, 24149 },
{ 20, 791000000UL, 6150, 6150, 6449, 832000000UL, 24150, 24150, 24449 },
{ 21, 1495900000UL, 6450, 6450, 6599, 1447900000UL, 24450, 24450, 24599 },
{ 22, 3510000000UL, 6600, 6600, 7399, 3410000000UL, 24600, 24600, 25399 },
{ 23, 2180000000UL, 7500, 7500, 7699, 2000000000UL, 25500, 25500, 25699 },
{ 24, 1525000000UL, 7700, 7700, 8039, 1626500000UL, 25700, 25700, 26039 },
{ 25, 1930000000UL, 8040, 8040, 8689, 1850000000UL, 26040, 26040, 26689 },
{ 33, 1900000000UL, 36000, 36000, 36199, 1900000000UL, 36000, 36000, 36199 },
{ 34, 2010000000UL, 36200, 36200, 36349, 2010000000UL, 36200, 36200, 36349 },
{ 35, 1850000000UL, 36350, 36350, 36949, 1850000000UL, 36350, 36350, 36949 },
{ 36, 1930000000UL, 36950, 36950, 37549, 1930000000UL, 36950, 36950, 37549 },
{ 37, 1910000000UL, 37550, 37550, 37749, 1910000000UL, 37550, 37550, 37749 },
{ 38, 2570000000UL, 37750, 37750, 38249, 2570000000UL, 37750, 37750, 38249 },
{ 39, 1880000000UL, 38250, 38250, 38649, 1880000000UL, 38250, 38250, 38649 },
{ 40, 2300000000UL, 38650, 38650, 39649, 2300000000UL, 38650, 38650, 39649 },
{ 41, 2496000000UL, 39650, 39650, 41589, 2496000000UL, 39650, 39650, 41589 },
{ 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 },
{ 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 },
};
int freq_to_arfcn10(int band, unsigned long freq)
{
int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]);
int i;
for (i = 0; i < N; i++) if (bands[i].band == band) break;
if (i == N) return -1;
if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq))
return -1;
return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off;
}
//-----------------------------------------------------------------------------
int
......@@ -2292,8 +2398,31 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ);
X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti;
X2AP_HANDOVER_REQ(msg).old_eNB_ue_s1ap_id=ue_context_pP->ue_context.eNB_ue_s1ap_id;
X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
measResultListEUTRA.list.array[0]->physCellId;
X2AP_HANDOVER_REQ(msg).ue_gummei.mcc=ue_context_pP->ue_context.ue_gummei.mcc;
X2AP_HANDOVER_REQ(msg).ue_gummei.mnc=ue_context_pP->ue_context.ue_gummei.mnc;
X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len=ue_context_pP->ue_context.ue_gummei.mnc_len;
X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code=ue_context_pP->ue_context.ue_gummei.mme_code;
X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id=ue_context_pP->ue_context.ue_gummei.mme_group_id;
// Don't know how to get this ID?
//X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id=0;
X2AP_HANDOVER_REQ(msg).security_capabilities=ue_context_pP->ue_context.security_capabilities;
memcpy (X2AP_HANDOVER_REQ(msg).kenb,
ue_context_pP->ue_context.kenb,
32);
X2AP_HANDOVER_REQ(msg).kenb_ncc= ue_context_pP->ue_context.kenb_ncc;
X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr;
// to be done
// X2AP_HANDOVER_REQ(msg).e_rabs_tobesetu=;
/* TODO: don't do that, X2AP should find the target by itself */
X2AP_HANDOVER_REQ(msg).target_mod_id = get_adjacent_cell_mod_id(X2AP_HANDOVER_REQ(msg).target_physCellId);
......@@ -2466,7 +2595,7 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
/* TODO: get proper UE rnti */
int rnti = taus() & 0xffff;
global_rnti = rnti;
global_rnti = rnti;
ue_context_target_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id], rnti);
if (ue_context_target_p != NULL) {
......@@ -2494,7 +2623,12 @@ global_rnti = rnti;
/* TODO: remove this hack */
ue_context_target_p->ue_context.handover_info->modid_t = mod_id;
ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id;
ue_context_target_p->ue_context.handover_info->ueid_s= m->source_rnti;
ue_context_target_p->ue_context.handover_info->ueid_s = m->source_rnti;
memset (ue_context_target_p->ue_context.nh, 0, 32);
ue_context_target_p->ue_context.nh_ncc = -1;
memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32);
ue_context_target_p->ue_context.kenb_ncc = m->kenb_ncc;
}
#if 0
......
......@@ -339,6 +339,8 @@ static void process_eNB_security_key (
/* Saves the security key */
memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH);
memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH);
ue_context_pP->ue_context.nh_ncc = -1;
for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]);
......@@ -682,6 +684,9 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
ue_context_pP->ue_context.rnti);
}
const Enb_properties_array_t *enb_properties_p = NULL;
enb_properties_p = enb_config_get();
if (rrcConnectionSetupComplete->registeredMME != NULL) {
/* Fill GUMMEI */
struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME;
......@@ -693,7 +698,8 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
/* Use first indicated PLMN MCC if it is defined */
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0];
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
ue_context_pP->ue_context.ue_gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0];
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
ue_context_pP->ue_context.rnti);
......@@ -702,24 +708,30 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
if (r_mme->plmn_Identity->mnc.list.count > 0) {
/* Use first indicated PLMN MNC if it is defined */
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0];
ue_context_pP->ue_context.ue_gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0];
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
ue_context_pP->ue_context.rnti);
}
} else {
const Enb_properties_array_t *enb_properties_p = NULL;
enb_properties_p = enb_config_get();
// actually the eNB configuration contains only one PLMN (can be up to 6)
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = enb_properties_p->properties[ctxt_pP->module_id]->mcc;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = enb_properties_p->properties[ctxt_pP->module_id]->mnc;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = enb_properties_p->properties[ctxt_pP->module_id]->mnc_digit_length;
}
/* save gummei in ue context for other procedures such as x2 ho */
ue_context_pP->ue_context.ue_gummei.mcc=enb_properties_p->properties[ctxt_pP->module_id]->mcc;
ue_context_pP->ue_context.ue_gummei.mnc=enb_properties_p->properties[ctxt_pP->module_id]->mnc;
ue_context_pP->ue_context.ue_gummei.mnc_len=enb_properties_p->properties[ctxt_pP->module_id]->mnc_digit_length;
}
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec);
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi);
ue_context_pP->ue_context.ue_gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec);
ue_context_pP->ue_context.ue_gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi);
MSC_LOG_TX_MESSAGE(
MSC_S1AP_ENB,
MSC_S1AP_MME,
......@@ -735,6 +747,19 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id,
ue_context_pP->ue_context.rnti);
} else {
// send the default GUMME even if the registered MME is not set
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = enb_properties_p->properties[ctxt_pP->module_id]->mcc;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = enb_properties_p->properties[ctxt_pP->module_id]->mnc;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = enb_properties_p->properties[ctxt_pP->module_id]->mnc_digit_length;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = 1;
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = 4;
// keep these values in Ue context
ue_context_pP->ue_context.ue_gummei.mcc = enb_properties_p->properties[ctxt_pP->module_id]->mcc;
ue_context_pP->ue_context.ue_gummei.mnc = enb_properties_p->properties[ctxt_pP->module_id]->mnc;
ue_context_pP->ue_context.ue_gummei.mnc_len = enb_properties_p->properties[ctxt_pP->module_id]->mnc_digit_length;
ue_context_pP->ue_context.ue_gummei.mme_code = 1;
ue_context_pP->ue_context.ue_gummei.mme_group_id = 4;
}
}
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, message_p);
......
......@@ -42,11 +42,19 @@
#include "x2ap_eNB_generate_messages.h"
#include "x2ap_eNB_encoder.h"
#include "x2ap_eNB_itti_messaging.h"
#include "RRC/LITE/defs.h"
#include "RRC/LITE/extern.h"
#include "secu_defs.h"
#include "rrc_eNB_UE_context.h"
#include "enb_config.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
extern unsigned char NB_eNB_INST;
extern int x2id_to_source_rnti[1];
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p)
......@@ -334,10 +342,34 @@ int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p,
INTPROTALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
char KeNB_star[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
uint8_t KeNB_star[32] = { 0 };
// find UE context
// use hack defined in x2ap_eNB.c in x2ap_eNB_handle_handover_req(...):
if ((instance_p->instance < 0) || (instance_p->instance >= NB_eNB_INST)) {
X2AP_ERROR("Failed to find RRC eNB instance %d\n", instance_p->instance);
return -1;
}
eNB_RRC_INST* rrc_instance = &eNB_rrc_inst[instance_p->instance];
struct rrc_eNB_ue_context_s* rrc_eNB_ue_context = rrc_eNB_get_ue_context(rrc_instance, x2id_to_source_rnti[0]);
if (!rrc_eNB_ue_context) {
X2AP_ERROR("Failed to find RRC UE context RNTI %X\n", x2id_to_source_rnti[0]);
return -1;
}
const Enb_properties_array_t *enb_properties = enb_config_get();
uint16_t pci = enb_properties->properties[instance_p->instance]->Nid_cell[0];
uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(enb_properties->properties[instance_p->instance]->eutra_band[0],
enb_properties->properties[instance_p->instance]->downlink_frequency[0]);
if (rrc_eNB_ue_context->ue_context.nh_ncc >= 0) {
derive_keNB_star (rrc_eNB_ue_context->ue_context.nh, pci, earfcn_dl, false, KeNB_star);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = rrc_eNB_ue_context->ue_context.nh_ncc;
} else { // first HO
derive_keNB_star (rrc_eNB_ue_context->ue_context.kenb, pci, earfcn_dl, false, KeNB_star);
// LG: really 1 ?
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
}
KENB_STAR_TO_BIT_STRING(KeNB_star,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
......
......@@ -234,8 +234,15 @@ x2ap_eNB_handle_handover_preparation(uint32_t assoc_id,
extern int x2id_to_source_rnti[1];
X2AP_HANDOVER_REQ(m).source_x2id = x2HandoverRequest->old_eNB_UE_X2AP_ID;
X2AP_HANDOVER_REQ(m).source_rnti = x2id_to_source_rnti[x2HandoverRequest->old_eNB_UE_X2AP_ID];
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, m);
return 0;
if ((x2HandoverRequest->uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf) &&
(x2HandoverRequest->uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.size == 256)) {
memcpy(X2AP_HANDOVER_REQ(m).kenb, x2HandoverRequest->uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32);
X2AP_HANDOVER_REQ(m).kenb_ncc = x2HandoverRequest->uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount;
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, m);
return 0;
} else {
return -1;
}
#if 0
if (x2SetupRequest->globalENB_ID.eNB_ID.present == X2ap_ENB_ID_PR_home_eNB_ID) {
......
......@@ -63,3 +63,45 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB
}
#endif
int
derive_keNB_star (
const uint8_t *kenb_32,
const uint16_t pci,
const uint32_t earfcn_dl,
const bool is_rel8_only,
uint8_t *kenb_star)
{
// see 33.401 section A.5 KeNB* derivation function
uint8_t s[10] = {0};
// FC = 0x13
s[0] = FC_KENB_STAR;
// P0 = PCI (target physical cell id)
s[1] = (pci & 0x0000ff00) >> 8;
s[2] = (pci & 0x000000ff);
// L0 = length of PCI (i.e. 0x00 0x02)
s[3] = 0x00;
s[4] = 0x02;
// P1 = EARFCN-DL (target physical cell downlink frequency)
if (is_rel8_only) {
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
s[6] = (earfcn_dl & 0x000000ff);
s[7] = 0x00;
s[8] = 0x02;
kdf (kenb_32, 32, s, 9, kenb_star, 32);
} else {
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
s[7] = (earfcn_dl & 0x000000ff);
s[8] = 0x00;
s[9] = 0x03;
kdf (kenb_32, 32, s, 10, kenb_star, 32);
}
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
// NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
// EARFCN-DL.
return 0;
}
......@@ -23,6 +23,7 @@
#define SECU_DEFS_H_
#include "security_types.h"
#include <stdbool.h>
#define EIA0_ALG_ID 0x00
#define EIA1_128_ALG_ID 0x01
......@@ -44,6 +45,9 @@ void kdf(const uint8_t *key,
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
int derive_keNB_star (const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
const bool is_rel8_only, uint8_t * kenb_star);
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t kasme[32], uint8_t *knas);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment