From 90231b57ad8e6a6954b2b7738cf0493b4571d5ad Mon Sep 17 00:00:00 2001 From: gauthier <gauthier@mycompany.com> Date: Tue, 23 Jun 2015 13:14:50 +0000 Subject: [PATCH] Still under construction git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7642 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- .../mme_test_s1_generate_scenario_from_pcap | 210 +++++++++++ openair-cn/TEST/oaisim_mme_test_s1c_s1ap.c | 337 ++++++++++++++++++ openair-cn/TEST/oaisim_mme_test_s1c_s1ap.h | 60 ++++ .../TEST/oaisim_mme_test_s1c_scenario.c | 286 +++++++++++++++ 4 files changed, 893 insertions(+) create mode 100755 openair-cn/TEST/mme_test_s1_generate_scenario_from_pcap create mode 100755 openair-cn/TEST/oaisim_mme_test_s1c_s1ap.c create mode 100755 openair-cn/TEST/oaisim_mme_test_s1c_s1ap.h create mode 100755 openair-cn/TEST/oaisim_mme_test_s1c_scenario.c diff --git a/openair-cn/TEST/mme_test_s1_generate_scenario_from_pcap b/openair-cn/TEST/mme_test_s1_generate_scenario_from_pcap new file mode 100755 index 00000000000..6a3e61091f2 --- /dev/null +++ b/openair-cn/TEST/mme_test_s1_generate_scenario_from_pcap @@ -0,0 +1,210 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +################################################################################ +# OpenAirInterface +# Copyright(c) 1999 - 2014 Eurecom +# +# OpenAirInterface is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# +# OpenAirInterface is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenAirInterface.The full GNU General Public License is +# included in this distribution in the file called "COPYING". If not, +# see <http://www.gnu.org/licenses/>. +# +# Contact Information +# OpenAirInterface Admin: openair_admin@eurecom.fr +# OpenAirInterface Tech : openair_tech@eurecom.fr +# OpenAirInterface Dev : openair4g-devel@eurecom.fr +# +# Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE +# +################################################################################ +import sys +import subprocess +import re +import socket +import datetime +from datetime import date +import os, errno +import argparse + + + + +parser = argparse.ArgumentParser() +parser.add_argument("--pcap_file", "-p", type=str,help="input pcap file to be translated") +args = parser.parse_args() + +pcap_file = args.pcap_file.strip() + +pcap_dissected_file = subprocess.check_output(["tshark", '-V', '-r' , pcap_file], stderr=subprocess.STDOUT) +pcap_hex_file = subprocess.check_output(["tshark", '-x', '-O', 'sctp', '-r', pcap_file]) +pcap_dissected_list = [] + +# split file content in lines +lines = pcap_dissected_file.splitlines() +message = {} +item_index = 0; +item_string = " " +fsm_state="search_frame" +for line in lines: + print ("INPUT LINE: %s " % line) + line = line.strip() + if line != "": + if fsm_state == "search_frame": + if line.startswith("Frame"): + message = {} + partition = line.split(' ',3) + message['frame'] = int(partition[1].strip(':')) + fsm_state = "search_ip" + print("Found Frame %d" % (message['frame'])) + + elif fsm_state == "search_ip": + if line.startswith("Internet Protocol Version"): + fsm_state = "fill_ip" + message['ip_fields'] = 0 + print("Found in Frame %d IP" % (message['frame'])) + + elif fsm_state == "fill_ip": + if line.startswith("Header length"): + partition = line.split(' ',4) + message['ip_header_length'] = int(partition[2]) + message['ip_fields'] += 1 + print("Found in Frame %d IP header length %d" % (message['frame'], int(partition[2]))) + if line.startswith("Total Length"): + partition = line.split(' ',4) + message['ip_total_length'] = int(partition[2]) + message['ip_fields'] += 1 + print("Found in Frame %d IP Total Length %d" % (message['frame'], int(partition[2]))) + if line.startswith("Protocol"): + partition = line.split(' ',4) + if partition[1] != "SCTP": + print("Error did not found in Frame %d SCTP" % (message['frame']))) + fsm_state="search_frame" + continue + else: + message['ip_protocol'] = partition[1] + message['ip_fields'] += 1 + print("Found in Frame %d SCTP" % (message['frame']))) + if message['ip_fields'] == 3: + fsm_state = "search_sctp" + print("in Frame %d searching S1AP" % (message['frame']))) + + elif fsm_state == "search_sctp": + if line.startswith("Internet Protocol Version"): + fsm_state = "fill_sctp" + message['sctp_fields'] = 0 + + elif fsm_state == "fill_sctp": + if line.startswith("Source port"): + partition = line.split(' ',4) + message['Source port'] = int(partition[2]) + message['sctp_fields'] += 1 + elif line.startswith("Destination port"): + partition = line.split(' ',4) + message['Destination port'] = int(partition[2]) + message['sctp_fields'] += 1 + elif line.startswith("Chunk length"): + partition = line.split(' ',4) + message['Chunk length'] = int(partition[2]) + message['sctp_fields'] += 1 + elif line.startswith("Stream Identifier"): + partition = line.split(' ',4) + message['Stream Identifier'] = int(partition[2]) + message['sctp_fields'] += 1 + elif line.startswith("Stream sequence number"): + partition = line.split(' ',4) + message['Stream sequence number'] = int(partition[3]) + message['sctp_fields'] += 1 + elif line.startswith("Chunk padding"): + partition = line.split(' ',4) + message['Chunk padding'] = int(partition[2]) + message['sctp_fields'] += 1 + if message['sctp_fields'] == 6: + fsm_state = "search_s1ap" + + elif fsm_state == "search_s1ap": + if line.startswith("S1 Application Protocol"): + fsm_state = "fill_s1ap" + message['s1ap_fields'] = 0 + print("in Frame %d Filling S1AP" % (message['frame']))) + + elif fsm_state == "fill_s1ap": + if line.startswith("S1AP-PDU:"): + partition = line.split(' ') + message['Pdu'] = partition[1] + message['s1ap_fields'] += 1 + elif line.startswith("procedureCode:"): + partition = line.split(' ') + message['procedureCode:'] = partition[1] + message['s1ap_fields'] += 1 + elif line.startswith("protocolIEs"): + partition = line.split(' ') + message['protocolIEs'] = int(partition[1]) + message['items'] = {} + elif line.startswith("Item"): + partition = line.split(' ') + item_index = partition[1].trim(':') + item_string = partition[2] + message['items'][item_string] = ' ' + print("Found in Frame %d S1AP Item %d %s" % (message['frame'], item_index, item_string))) + if item_string == id-E-RABToBeSetupListCtxtSUReq: + elif item_string == id-E-RABToBeSetupListCtxtSUReq: + elif line.startswith("nAS-PDU"): + partition = line.split(' ') + nas_bytes = partition[1].trim('.') + message['items'].append + print("Found in Frame %d Stream sequence number" % (message['frame'], int(partition[3]))) + + if message['s1ap_fields'] == 6: + pcap_dissected_list.append(message) + fsm_state = "search_frame" + +for message in pcap_dissected_list: + print("Message:\n" ) + print(" %s" % (message)) + +lines = pcap_hex_file.splitlines() +message = {} +message_index = 0 +fsm_state="search_frame" +for line in lines: + print ("INPUT LINE: %s " % line) + line = line.strip() + if line != "": + if fsm_state == "search_frame": + if line.startswith("Frame"): + partition = line.split(' ',3) + fsm_state = "search_s1ap" + + elif fsm_state == "search_s1ap": + if line.startswith("S1 Application Protocol"): + fsm_state = "fill_s1ap" + message = pcap_dissected_list[message_index] + message['s1ap_byte_offset'] = 0 + message['dumped'] = [] + message_index += 1 + + elif fsm_state == "fill_s1ap": + if not line.startswith("Frame"): + bytes = line.split(' ') + byte_index = int(bytes[0],16) + if byte_index == message['s1ap_byte_offset']: + message['s1ap_byte_offset'] += 16 + for byte in bytes: + message['dumped'].append(byte) + message['s1ap_byte_offset'] += 1 + else: + fsm_state="search_frame" + +print (" %s " % ( pcap_dissected_list ) ) + diff --git a/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.c b/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.c new file mode 100755 index 00000000000..a46c8fa6b49 --- /dev/null +++ b/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.c @@ -0,0 +1,337 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + +*******************************************************************************/ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sched.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <syscall.h> + + +#include "tree.h" +#include "queue.h" +#include "intertask_interface.h" +#include "s1ap_eNB_default_values.h" +#include "s1ap_common.h" +#include "s1ap_ies_defs.h" +#include "s1ap_eNB_defs.h" +#include "s1ap_eNB_management_procedures.h" +#include "assertions.h" + +#include "platform_types.h" +#include "oaisim_mme_test_s1c.h" + + +void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) +{ + int result; + + DevAssert(sctp_data_ind != NULL); + mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + + +void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown) +{ + if (sctp_shutdown) { + /* A previously connected MME has been shutdown */ + + /* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated MME */ + if (mme_desc_p->state == S1AP_ENB_STATE_CONNECTED) { + mme_desc_p->state = S1AP_ENB_STATE_DISCONNECTED; + + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb > 0) { + /* Decrease associated MME number */ + mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb --; + } + + /* If there are no more associated MME, inform eNB app */ + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND); + S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0; + itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); + } + } + } else { + /* Check that at least one setup message is pending */ + DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance, + mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0); + + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) { + /* Decrease pending messages number */ + mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --; + } + + /* If there are no more pending messages, inform eNB app */ + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF); + S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); + } + } +} + +void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) +{ + s1ap_eNB_instance_t *instance_p; + s1ap_eNB_mme_data_t *s1ap_mme_data_p; + + DevAssert(sctp_new_association_resp != NULL); + + instance_p = s1ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1, + sctp_new_association_resp->ulp_cnx_id); + DevAssert(s1ap_mme_data_p != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + + return; + } + + /* Update parameters */ + s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; + s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + + /* Prepare new S1 Setup Request */ + mme_test_s1_start_test(instance_p, s1ap_mme_data_p); +} + +void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, + net_ip_address_t *mme_ip_address, + net_ip_address_t *local_ip_addr) +{ + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL; + + DevAssert(instance_p != NULL); + DevAssert(mme_ip_address != NULL); + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); + + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + + sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; + + memcpy(&sctp_new_association_req_p->remote_address, + mme_ip_address, + sizeof(*mme_ip_address)); + + memcpy(&sctp_new_association_req_p->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + + /* Create new MME descriptor */ + s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); + DevAssert(s1ap_mme_data_p != NULL); + + s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id(); + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + s1ap_mme_data_p->assoc_id = -1; + s1ap_mme_data_p->s1ap_eNB_instance = instance_p; + + STAILQ_INIT(&s1ap_mme_data_p->served_gummei); + + /* Insert the new descriptor in list of known MME + * but not yet associated. + */ + RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p); + s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; + instance_p->s1ap_mme_nb ++; + instance_p->s1ap_mme_pending_nb ++; + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); +} + + + +void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB) +{ + s1ap_eNB_instance_t *new_instance; + uint8_t index; + + DevAssert(s1ap_register_eNB != NULL); + + /* Look if the provided instance already exists */ + new_instance = s1ap_eNB_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same eNB */ + DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0); + DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0); + DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0); + DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0); + DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0); + DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0); + DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0); + } else { + new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); + DevAssert(new_instance != NULL); + + RB_INIT(&new_instance->s1ap_ue_head); + RB_INIT(&new_instance->s1ap_mme_head); + + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->eNB_name = s1ap_register_eNB->eNB_name; + new_instance->eNB_id = s1ap_register_eNB->eNB_id; + new_instance->cell_type = s1ap_register_eNB->cell_type; + new_instance->tac = s1ap_register_eNB->tac; + new_instance->mcc = s1ap_register_eNB->mcc; + new_instance->mnc = s1ap_register_eNB->mnc; + new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length; + new_instance->default_drx = s1ap_register_eNB->default_drx; + + /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ + s1ap_eNB_insert_new_instance(new_instance); + + S1AP_DEBUG("Registered new eNB[%d] and %s eNB id %u\n", + instance, + s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", + s1ap_register_eNB->eNB_id); + } + + DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, + S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); + + /* Trying to connect to provided list of MME ip address */ + for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { + s1ap_eNB_register_mme(new_instance, &s1ap_register_eNB->mme_ip_address[index], + &s1ap_register_eNB->enb_ip_address); + } +} + + + + +void *s1ap_eNB_task(void *arg) +{ + MessageDef *received_msg = NULL; + int result; + + S1AP_DEBUG("Starting S1AP layer\n"); + + s1ap_eNB_prepare_internal_data(); + + itti_mark_task_ready(TASK_S1AP); + + while (1) { + itti_receive_msg(TASK_S1AP, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + itti_exit_task(); + break; + + case S1AP_REGISTER_ENB_REQ: { + /* Register a new eNB. + * in Virtual mode eNBs will be distinguished using the mod_id/ + * Each eNB has to send an S1AP_REGISTER_ENB message with its + * own parameters. + */ + s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_REGISTER_ENB_REQ(received_msg)); + } + break; + + case SCTP_NEW_ASSOCIATION_RESP: { + s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + } + break; + + case SCTP_DATA_IND: { + s1ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); + } + break; + + + + default: + S1AP_ERROR("Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } + + return NULL; +} diff --git a/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.h b/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.h new file mode 100755 index 00000000000..43d2681c9a2 --- /dev/null +++ b/openair-cn/TEST/oaisim_mme_test_s1c_s1ap.h @@ -0,0 +1,60 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + +*******************************************************************************/ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sched.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <syscall.h> + +void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind); + +void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + +void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown); + +void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, + net_ip_address_t *mme_ip_address, + net_ip_address_t *local_ip_addr); +void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); +void *s1ap_eNB_task(void *arg); diff --git a/openair-cn/TEST/oaisim_mme_test_s1c_scenario.c b/openair-cn/TEST/oaisim_mme_test_s1c_scenario.c new file mode 100755 index 00000000000..416ac999042 --- /dev/null +++ b/openair-cn/TEST/oaisim_mme_test_s1c_scenario.c @@ -0,0 +1,286 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + +*******************************************************************************/ +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#include <ctype.h> + +#include "oaisim_mme_test_s1c_scenario.h" + +int scenario_index = 0; +int scenario_message_index = 0; +int debug = 0; +int error_count = 0; +int break_on_error = 0; + + +extern s1ap_message_test_t s1ap_scenario1[]; + +s1ap_message_test_t s1ap_scenarios[][] = {s1ap_scenario1}; + +/* -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; + } +} + -- GitLab