S1AP_UE_CONTEXT_RELEASE_COMPLETE, NAS test
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7492 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -461,7 +461,7 @@ void mme_app_handle_s1ap_ue_context_release_req(const s1ap_ue_context_release_re
|
||||
if (ue_context_p == NULL) {
|
||||
MSC_LOG_EVENT(
|
||||
MSC_MMEAPP_MME,
|
||||
"S1AP_UE_CONTEXT_RELEASE_REQ Unknown ue %u",s1ap_ue_context_release_req->mme_ue_s1ap_id);
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_REQ Unknown mme_ue_s1ap_id 0x%06"PRIX32" ",s1ap_ue_context_release_req->mme_ue_s1ap_id);
|
||||
MME_APP_ERROR("UE context doesn't exist for UE 0x%06"PRIX32"/dec%u\n",
|
||||
s1ap_ue_context_release_req->mme_ue_s1ap_id,
|
||||
s1ap_ue_context_release_req->mme_ue_s1ap_id);
|
||||
@@ -469,3 +469,41 @@ void mme_app_handle_s1ap_ue_context_release_req(const s1ap_ue_context_release_re
|
||||
}
|
||||
mme_app_send_s11_release_access_bearers_req(ue_context_p);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mme_app_handle_s1ap_ue_context_release_complete(const s1ap_ue_context_release_complete_t const *s1ap_ue_context_release_complete)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
struct ue_context_s *ue_context_p = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
MME_APP_DEBUG("Received S1AP_UE_CONTEXT_RELEASE_COMPLETE from S1AP\n");
|
||||
|
||||
ue_context_p = mme_ue_context_exists_nas_ue_id(&mme_app_desc.mme_ue_contexts, s1ap_ue_context_release_complete->mme_ue_s1ap_id);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
MSC_LOG_EVENT(
|
||||
MSC_MMEAPP_MME,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE Unknown mme_ue_s1ap_id 0x%06"PRIX32" ",s1ap_ue_context_release_complete->mme_ue_s1ap_id);
|
||||
MME_APP_ERROR("UE context doesn't exist for mme_ue_s1ap_id 0x%06"PRIX32"/dec%u\n",
|
||||
s1ap_ue_context_release_complete->mme_ue_s1ap_id,
|
||||
s1ap_ue_context_release_complete->mme_ue_s1ap_id);
|
||||
return;
|
||||
}
|
||||
message_p = itti_alloc_new_message(TASK_MME_APP, S1AP_DEREGISTER_UE_REQ);
|
||||
memset((void*)&message_p->ittiMsg.s1ap_deregister_ue_req,
|
||||
0,
|
||||
sizeof(s1ap_deregister_ue_req_t));
|
||||
|
||||
S1AP_DEREGISTER_UE_REQ(message_p).mme_ue_s1ap_id = s1ap_ue_context_release_complete->mme_ue_s1ap_id;
|
||||
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_MMEAPP_MME,
|
||||
MSC_NAS_MME,
|
||||
NULL,0,
|
||||
"0 S1AP_DEREGISTER_UE_REQ");
|
||||
|
||||
itti_send_msg_to_task(TASK_NAS_MME, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
@@ -157,6 +157,10 @@ void *mme_app_thread(void *args)
|
||||
}
|
||||
break;
|
||||
|
||||
case S1AP_UE_CONTEXT_RELEASE_COMPLETE: {
|
||||
mme_app_handle_s1ap_ue_context_release_complete(&received_message_p->ittiMsg.s1ap_ue_context_release_complete);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
MME_APP_DEBUG("Unkwnon message ID %d:%s\n",
|
||||
ITTI_MSG_ID(received_message_p), ITTI_MSG_NAME(received_message_p));
|
||||
|
||||
@@ -122,14 +122,14 @@ typedef enum {
|
||||
} emm_ksi_t;
|
||||
|
||||
/* EPS NAS security context structure */
|
||||
typedef struct {
|
||||
typedef struct emm_security_context_s {
|
||||
emm_ksi_t type; /* Type of security context */
|
||||
int eksi; /* NAS key set identifier for E-UTRAN */
|
||||
OctetString kasme; /* ASME security key (native context) */
|
||||
//OctetString ksgsn; /* SGSN security key (mapped context) */
|
||||
OctetString knas_enc; /* NAS cyphering key */
|
||||
OctetString knas_int; /* NAS integrity key */
|
||||
struct {
|
||||
struct count_s{
|
||||
UInt32_t spare:8;
|
||||
UInt32_t overflow:16;
|
||||
UInt32_t seq_num:8;
|
||||
@@ -205,7 +205,7 @@ typedef enum {
|
||||
* for PLMN selection, cell selection/re-selection and handover.
|
||||
* The maximum number of possible entries in the stored list is 16.
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct emm_nvdata_s {
|
||||
imsi_t imsi;
|
||||
plmn_t rplmn; /* The registered PLMN */
|
||||
/* List of equivalent PLMNs */
|
||||
@@ -217,7 +217,7 @@ typedef struct {
|
||||
* Structure of the EMM data
|
||||
* -------------------------
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct emm_data_s {
|
||||
int usim_is_valid; /* Indication of USIM data validity */
|
||||
|
||||
imei_t *imei; /* IMEI read from the UE's non-volatile memory*/
|
||||
@@ -425,6 +425,9 @@ struct emm_data_context_s *emm_data_context_remove(
|
||||
emm_data_t *_emm_data, struct emm_data_context_s *elm);
|
||||
|
||||
void emm_data_context_add(emm_data_t *emm_data, struct emm_data_context_s *elm);
|
||||
void emm_data_context_dump(struct emm_data_context_s *elm_pP);
|
||||
|
||||
void emm_data_context_dump_all(void);
|
||||
|
||||
#endif // NAS_MME
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "tree.h"
|
||||
#include "emmData.h"
|
||||
#include "nas_log.h"
|
||||
#include "security_types.h"
|
||||
|
||||
static inline
|
||||
int emm_data_ctxt_compare_ueid(struct emm_data_context_s *p1,
|
||||
@@ -89,4 +90,96 @@ void emm_data_context_add(emm_data_t *emm_data, struct emm_data_context_s *elm)
|
||||
RB_INSERT(emm_data_context_map, &emm_data->ctx_map, elm);
|
||||
}
|
||||
|
||||
void emm_data_context_dump(struct emm_data_context_s *elm_pP)
|
||||
{
|
||||
if (elm_pP != NULL) {
|
||||
char imsi_str[16];
|
||||
char guti_str[22];
|
||||
int k, size, remaining_size;
|
||||
char key_string[KASME_LENGTH_OCTETS*2];
|
||||
LOG_TRACE(INFO, "EMM-CTX: ue id: 0x%06"PRIX32" (UE identifier)", elm_pP->ueid);
|
||||
LOG_TRACE(INFO, " is_dynamic: %u (Dynamically allocated context indicator)", elm_pP->is_dynamic);
|
||||
LOG_TRACE(INFO, " is_attached: %u (Attachment indicator)", elm_pP->is_attached);
|
||||
LOG_TRACE(INFO, " is_emergency: %u (Emergency bearer services indicator)", elm_pP->is_emergency);
|
||||
NAS_IMSI2STR(elm_pP->imsi, imsi_str, 16);
|
||||
LOG_TRACE(INFO, " imsi: %s (The IMSI provided by the UE or the MME)", imsi_str);
|
||||
LOG_TRACE(INFO, " imei: TODO (The IMEI provided by the UE)");
|
||||
LOG_TRACE(INFO, " guti_is_new: %u (New GUTI indicator)", elm_pP->guti_is_new);
|
||||
GUTI2STR(elm_pP->guti, guti_str, 22);
|
||||
LOG_TRACE(INFO, " guti: %s (The GUTI assigned to the UE)", guti_str);
|
||||
GUTI2STR(elm_pP->old_guti, guti_str, 22);
|
||||
LOG_TRACE(INFO, " old_guti: %s (The old GUTI)", guti_str);
|
||||
LOG_TRACE(INFO, " n_tacs: %u (Number of consecutive tracking areas the UE is registered to)", elm_pP->n_tacs);
|
||||
LOG_TRACE(INFO, " tac: 0x%04x (Code of the first tracking area the UE is registered to)", elm_pP->n_tacs);
|
||||
LOG_TRACE(INFO, " ksi: %u (Security key set identifier provided by the UE)", elm_pP->ksi);
|
||||
|
||||
LOG_TRACE(INFO, " auth_vector: (EPS authentication vector)");
|
||||
LOG_TRACE(INFO, " kasme: "KASME_FORMAT""KASME_FORMAT, KASME_DISPLAY_1(elm_pP->vector.kasme), KASME_DISPLAY_2(elm_pP->vector.kasme));
|
||||
LOG_TRACE(INFO, " rand: "RAND_FORMAT, RAND_DISPLAY(elm_pP->vector.rand));
|
||||
LOG_TRACE(INFO, " autn: "AUTN_FORMAT, AUTN_DISPLAY(elm_pP->vector.autn));
|
||||
for (k = 0; k < XRES_LENGTH_MAX; k++) {sprintf(&key_string[k * 3], "%02x,", elm_pP->vector.xres[k]);}
|
||||
key_string[k * 3 - 1] = '\0';
|
||||
LOG_TRACE(INFO, " xres: %s\n", key_string);
|
||||
|
||||
if (elm_pP->security != NULL) {
|
||||
LOG_TRACE(INFO, " security context: (Current EPS NAS security context)");
|
||||
LOG_TRACE(INFO, " type: %s (Type of security context)",
|
||||
(elm_pP->security->type == EMM_KSI_NOT_AVAILABLE)?"KSI_NOT_AVAILABLE":(elm_pP->security->type == EMM_KSI_NATIVE)?"KSI_NATIVE":"KSI_MAPPED");
|
||||
LOG_TRACE(INFO, " eksi: %u (NAS key set identifier for E-UTRAN)", elm_pP->security->eksi);
|
||||
|
||||
if (elm_pP->security->kasme.length > 0) {
|
||||
size = 0;
|
||||
size = 0;remaining_size=KASME_LENGTH_OCTETS*2;
|
||||
for (k = 0; k < elm_pP->security->kasme.length; k++) {
|
||||
size +=snprintf(&key_string[size], remaining_size, "0x%x ", elm_pP->security->kasme.value[k]);
|
||||
remaining_size -= size;
|
||||
}
|
||||
} else {
|
||||
size +=snprintf(&key_string[0], remaining_size, "None");
|
||||
}
|
||||
LOG_TRACE(INFO, " kasme: %s (ASME security key (native context))", key_string);
|
||||
if (elm_pP->security->knas_enc.length > 0) {
|
||||
size = 0;
|
||||
size = 0;remaining_size=KASME_LENGTH_OCTETS*2;
|
||||
for (k = 0; k < elm_pP->security->knas_enc.length; k++) {
|
||||
size +=snprintf(&key_string[size], remaining_size, "0x%x ", elm_pP->security->knas_enc.value[k]);
|
||||
remaining_size -= size;
|
||||
}
|
||||
} else {
|
||||
size +=snprintf(&key_string[0], remaining_size, "None");
|
||||
}
|
||||
LOG_TRACE(INFO, " knas_enc: %s (NAS cyphering key)", key_string);
|
||||
if (elm_pP->security->knas_int.length > 0) {
|
||||
size = 0;remaining_size=KASME_LENGTH_OCTETS*2;
|
||||
for (k = 0; k < elm_pP->security->knas_int.length; k++) {
|
||||
size +=snprintf(&key_string[size], remaining_size, "0x%x ", elm_pP->security->knas_int.value[k]);
|
||||
remaining_size -= size;
|
||||
}
|
||||
} else {
|
||||
size +=snprintf(&key_string[0], remaining_size, "None");
|
||||
}
|
||||
LOG_TRACE(INFO, " knas_int: %s (NAS integrity key)", key_string);
|
||||
LOG_TRACE(INFO, " dl_count.overflow: %u ", elm_pP->security->dl_count.overflow);
|
||||
LOG_TRACE(INFO, " dl_count.seq_num: %u ", elm_pP->security->dl_count.seq_num);
|
||||
LOG_TRACE(INFO, " ul_count.overflow: %u ", elm_pP->security->ul_count.overflow);
|
||||
LOG_TRACE(INFO, " ul_count.seq_num: %u ", elm_pP->security->ul_count.seq_num);
|
||||
LOG_TRACE(INFO, " TODO capability");
|
||||
LOG_TRACE(INFO, " selected_algorithms.encryption: %x ", elm_pP->security->selected_algorithms.encryption);
|
||||
LOG_TRACE(INFO, " selected_algorithms.integrity: %x ", elm_pP->security->selected_algorithms.integrity);
|
||||
} else {
|
||||
LOG_TRACE(INFO, " No security context");
|
||||
}
|
||||
LOG_TRACE(INFO, " _emm_fsm_status %u ", elm_pP->_emm_fsm_status);
|
||||
LOG_TRACE(INFO, " TODO esm_data_ctx");
|
||||
}
|
||||
}
|
||||
|
||||
void emm_data_context_dump_all(void)
|
||||
{
|
||||
struct emm_data_context_s *elm_p = NULL;
|
||||
LOG_TRACE(INFO, "EMM-CTX - Dump all contexts:");
|
||||
RB_FOREACH(elm_p, emm_data_context_map,&_emm_data.ctx_map) {
|
||||
emm_data_context_dump(elm_p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -171,7 +171,11 @@ static int _emm_cn_deregister_ue(const UInt32_t ue_id)
|
||||
int rc = RETURNok;
|
||||
|
||||
LOG_FUNC_IN;
|
||||
|
||||
LOG_TRACE(WARNING, "EMM-PROC - "
|
||||
"TODO deregister UE %u, following procedure is a test");
|
||||
emm_proc_detach_request(ue_id, EMM_DETACH_TYPE_EPS /* ??? emm_proc_detach_type_t*/,
|
||||
1 /*switch_off*/, 0 /*native_ksi*/, 0 /*ksi*/,
|
||||
NULL /*guti*/, NULL /*imsi*/, NULL /*imei*/);
|
||||
LOG_FUNC_RETURN (rc);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ int nas_log_func_indent;
|
||||
* or disable specific logging traces)
|
||||
*/
|
||||
typedef struct {
|
||||
#define LOG_PREFIX_SIZE 96
|
||||
#define LOG_PREFIX_SIZE 118
|
||||
char prefix[LOG_PREFIX_SIZE];
|
||||
unsigned char filter;
|
||||
int indent;
|
||||
@@ -157,7 +157,17 @@ void nas_log_init(char filter)
|
||||
***************************************************************************/
|
||||
void log_data(const char* filename, int line)
|
||||
{
|
||||
snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s[%d]", filename, line);
|
||||
int len = strlen(filename) + 2 + 1; //2:[], 1:/0
|
||||
if (line > 9999) len+=5;
|
||||
else if (line > 999) len+=4;
|
||||
else if (line > 99) len+=3;
|
||||
else if (line > 9) len+=2;
|
||||
else len+=1;
|
||||
if (len > LOG_PREFIX_SIZE) {
|
||||
snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", &filename[len - LOG_PREFIX_SIZE], line);
|
||||
} else {
|
||||
snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", filename, line);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -190,7 +200,7 @@ void log_trace(log_severity_t severity, const char* data, ...)
|
||||
* name and line number from where the data have been logged) and
|
||||
* the severity level.
|
||||
*/
|
||||
fprintf(stderr, "%s%-60.58s%-10s", _log_context.level[severity].color,
|
||||
fprintf(stderr, "%s%-120.118s%-10s", _log_context.level[severity].color,
|
||||
_log_context.prefix, _log_context.level[severity].name);
|
||||
{
|
||||
/* Next, perform indentation for FUNC logging trace */
|
||||
@@ -199,7 +209,7 @@ void log_trace(log_severity_t severity, const char* data, ...)
|
||||
}
|
||||
|
||||
for (i=0; i<_log_context.indent; i++) {
|
||||
fprintf(stderr, "\t");
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
|
||||
if (severity == FUNC_IN) {
|
||||
|
||||
@@ -812,7 +812,8 @@ int s1ap_mme_handle_ue_context_release_complete(uint32_t assoc_id,
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
S1ap_UEContextReleaseCompleteIEs_t *ueContextReleaseComplete_p;
|
||||
ue_description_t *ue_ref = NULL;
|
||||
ue_description_t *ue_ref = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
ueContextReleaseComplete_p = &message->msg.s1ap_UEContextReleaseCompleteIEs;
|
||||
MSC_LOG_RX_MESSAGE(
|
||||
@@ -839,6 +840,24 @@ int s1ap_mme_handle_ue_context_release_complete(uint32_t assoc_id,
|
||||
/* eNB has sent a release complete message. We can safely remove UE context.
|
||||
* TODO: inform NAS and remove e-RABS.
|
||||
*/
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
|
||||
AssertFatal(message_p != NULL,"itti_alloc_new_message Failed");
|
||||
memset((void*)&message_p->ittiMsg.s1ap_ue_context_release_complete,
|
||||
0,
|
||||
sizeof(s1ap_ue_context_release_complete_t));
|
||||
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(message_p).mme_ue_s1ap_id = ue_ref->mme_ue_s1ap_id;
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_S1AP_MME,
|
||||
MSC_MMEAPP_MME,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE mme_ue_s1ap_id "S1AP_UE_ID_FMT" ",
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(message_p).mme_ue_s1ap_id);
|
||||
|
||||
itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p);
|
||||
|
||||
s1ap_remove_ue(ue_ref);
|
||||
S1AP_DEBUG("Removed UE "S1AP_UE_ID_FMT"\n",
|
||||
(uint32_t)ueContextReleaseComplete_p->mme_ue_s1ap_id);
|
||||
|
||||
@@ -61,256 +61,13 @@
|
||||
static void get_options (int argc, char **argv);
|
||||
static uint32_t eNB_app_register(const uint32_t enb_id_start, const uint32_t enb_id_end, const Enb_properties_array_t *enb_properties);
|
||||
static void *eNB_app_task (void *args_p);
|
||||
static void mme_test_s1_start_test(instance_t instance);
|
||||
//------------------------------------------------------------------------------
|
||||
static char *conf_config_file_name = NULL;
|
||||
static char *itti_dump_file = NULL;
|
||||
const Enb_properties_array_t *enb_properties = NULL;
|
||||
int16_t glog_level = LOG_INFO;
|
||||
int16_t glog_verbosity = LOG_MED;
|
||||
//------------------------------------------------------------------------------
|
||||
int debug = 0;
|
||||
int error_count = 0;
|
||||
int break_on_error = 0;
|
||||
|
||||
/* -1 means invalid */
|
||||
static const signed char hex_digits[0x100] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
fail (const char *format, ...)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
char str[1024];
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
vsnprintf ( str, sizeof(str), format, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
fputs(str, stderr);
|
||||
error_count++;
|
||||
|
||||
if (break_on_error)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
success (const char *format, ...)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
char str[1024];
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
vsnprintf ( str, sizeof(str), format, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
fputs(str, stderr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
escapeprint (const char *str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
|
||||
printf (" (length %d bytes):\n\t", (int) len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (((str[i] & 0xFF) >= 'A' && (str[i] & 0xFF) <= 'Z') ||
|
||||
((str[i] & 0xFF) >= 'a' && (str[i] & 0xFF) <= 'z') ||
|
||||
((str[i] & 0xFF) >= '0' && (str[i] & 0xFF) <= '9')
|
||||
|| (str[i] & 0xFF) == ' ' || (str[i] & 0xFF) == '.')
|
||||
printf ("%c", (str[i] & 0xFF));
|
||||
else
|
||||
printf ("\\x%02X", (str[i] & 0xFF));
|
||||
|
||||
if ((i + 1) % 16 == 0 && (i + 1) < len)
|
||||
printf ("'\n\t'");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
hexprint (const void *_str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
const char* str = _str;
|
||||
|
||||
printf ("\t;; ");
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf ("%02x ", (str[i] & 0xFF));
|
||||
|
||||
if ((i + 1) % 8 == 0)
|
||||
printf (" ");
|
||||
|
||||
if ((i + 1) % 16 == 0 && i + 1 < len)
|
||||
printf ("\n\t;; ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
binprint (const void *_str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
const char* str = _str;
|
||||
|
||||
printf ("\t;; ");
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf ("%d%d%d%d%d%d%d%d ",
|
||||
(str[i] & 0xFF) & 0x80 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x40 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x20 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x10 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x08 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x04 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x02 ? 1 : 0, (str[i] & 0xFF) & 0x01 ? 1 : 0);
|
||||
|
||||
if ((i + 1) % 3 == 0)
|
||||
printf (" ");
|
||||
|
||||
if ((i + 1) % 6 == 0 && i + 1 < len)
|
||||
printf ("\n\t;; ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
compare_buffer(const uint8_t *buffer, const uint32_t length_buffer,
|
||||
const uint8_t *pattern, const uint32_t length_pattern)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int i;
|
||||
|
||||
if (length_buffer != length_pattern) {
|
||||
printf("Length mismatch, expecting %d bytes, got %d bytes\n", length_pattern,
|
||||
length_buffer);
|
||||
hexprint(buffer, length_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length_buffer; i++) {
|
||||
if (pattern[i] != buffer[i]) {
|
||||
printf("Expecting:\n");
|
||||
hexprint(pattern, length_pattern);
|
||||
printf("Received:\n");
|
||||
hexprint(buffer, length_buffer);
|
||||
printf("Mismatch fount in byte %d\nExpecting 0x%02x, got 0x%02x\n",
|
||||
i, pattern[i], buffer[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned
|
||||
decode_hex_length(const char *h)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned char *hex = (const unsigned char *) h;
|
||||
unsigned count;
|
||||
unsigned i;
|
||||
|
||||
for (count = i = 0; hex[i]; i++) {
|
||||
if (isspace(hex[i]))
|
||||
continue;
|
||||
|
||||
if (hex_digits[hex[i]] < 0)
|
||||
abort();
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count % 2)
|
||||
abort();
|
||||
|
||||
return count / 2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
decode_hex(uint8_t *dst, const char *h)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned char *hex = (const unsigned char *) h;
|
||||
unsigned i = 0;
|
||||
|
||||
for (;;) {
|
||||
int high, low;
|
||||
|
||||
while (*hex && isspace(*hex))
|
||||
hex++;
|
||||
|
||||
if (!*hex)
|
||||
return 1;
|
||||
|
||||
high = hex_digits[*hex++];
|
||||
|
||||
if (high < 0)
|
||||
return 0;
|
||||
|
||||
while (*hex && isspace(*hex))
|
||||
hex++;
|
||||
|
||||
if (!*hex)
|
||||
return 0;
|
||||
|
||||
low = hex_digits[*hex++];
|
||||
|
||||
if (low < 0)
|
||||
return 0;
|
||||
|
||||
dst[i++] = (high << 4) | low;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t *
|
||||
decode_hex_dup(const char *hex)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t *p;
|
||||
unsigned length = decode_hex_length(hex);
|
||||
|
||||
p = malloc(length * sizeof(uint8_t));
|
||||
|
||||
if (decode_hex(p, hex))
|
||||
return p;
|
||||
else {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void get_options (int argc, char **argv)
|
||||
@@ -360,6 +117,7 @@ static uint32_t eNB_app_register(const uint32_t enb_id_start, const uint32_t enb
|
||||
struct in_addr addr;
|
||||
|
||||
|
||||
// 1 eNB should be max.
|
||||
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
|
||||
{
|
||||
s1ap_register_enb_req_t *s1ap_register_eNB;
|
||||
@@ -470,11 +228,7 @@ static void *eNB_app_task(void *args_p)
|
||||
/* Check if all register eNB requests have been processed */
|
||||
if (register_enb_pending == 0) {
|
||||
if (registered_enb == enb_nb) {
|
||||
/* If all eNB are registered, start L2L1 task */
|
||||
MessageDef *msg_init_p;
|
||||
|
||||
msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
|
||||
itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
|
||||
mme_test_s1_start_test();
|
||||
|
||||
|
||||
} else {
|
||||
@@ -529,6 +283,18 @@ static void *eNB_app_task(void *args_p)
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mme_test_s1_start_test(instance_t instance)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
s1ap_eNB_itti_send_sctp_data_req(instance,
|
||||
int32_t assoc_id,
|
||||
s1ap_scenario1[scenario_message_index].buffer,
|
||||
s1ap_scenario1[scenario_message_index].buf_len,
|
||||
s1ap_scenario1[scenario_message_index].sctp_stream_id);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mme_test_s1_notify_sctp_data_ind(uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -28,13 +28,4 @@
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
void fail (const char *format, ...);
|
||||
void success (const char *format, ...);
|
||||
void escapeprint (const char *str, size_t len);
|
||||
void hexprint (const void *_str, size_t len);
|
||||
void binprint (const void *_str, size_t len);
|
||||
int compare_buffer(const uint8_t *buffer, const uint32_t length_buffer, const uint8_t *pattern, const uint32_t length_pattern);
|
||||
unsigned decode_hex_length(const char *h);
|
||||
int decode_hex(uint8_t *dst, const char *h);
|
||||
uint8_t *decode_hex_dup(const char *hex);
|
||||
void mme_test_s1_notify_sctp_data_ind(uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length);
|
||||
|
||||
@@ -39,7 +39,18 @@ typedef enum entity_s{
|
||||
typedef struct s1ap_test_s{
|
||||
char *procedure_name;
|
||||
uint8_t buffer[MME_TEST_S1_MAX_BUF_LENGTH];
|
||||
uint16_t dont_check[MME_TEST_S1_MAX_BYTES_TEST];
|
||||
uint16_t dont_check[MME_TEST_S1_MAX_BYTES_TEST]; // bytes index test that can be omitted
|
||||
uint32_t buf_len;
|
||||
entity_t originating;
|
||||
uint16_t sctp_stream_id;
|
||||
} s1ap_test_t;
|
||||
|
||||
void fail (const char *format, ...);
|
||||
void success (const char *format, ...);
|
||||
void escapeprint (const char *str, size_t len);
|
||||
void hexprint (const void *_str, size_t len);
|
||||
void binprint (const void *_str, size_t len);
|
||||
int compare_buffer(const uint8_t *buffer, const uint32_t length_buffer, const uint8_t *pattern, const uint32_t length_pattern);
|
||||
unsigned decode_hex_length(const char *h);
|
||||
int decode_hex(uint8_t *dst, const char *h);
|
||||
uint8_t *decode_hex_dup(const char *hex);
|
||||
|
||||
@@ -47,6 +47,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 96,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
@@ -63,6 +64,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 65,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
@@ -78,6 +80,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 62,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
@@ -92,6 +95,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 42,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
@@ -107,6 +111,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 59,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
@@ -130,6 +135,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 191,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
@@ -158,6 +164,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 64,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
@@ -174,6 +181,7 @@ s1ap_test_t s1ap_scenario1[] = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 64,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user