update it

This commit is contained in:
Sukchan Lee 2017-03-05 13:03:11 +09:00
parent 4f00585f90
commit 823f3c3a0f
7 changed files with 243 additions and 82 deletions

View File

@ -8,6 +8,14 @@
#include "context.h"
#include "s1ap_message.h"
#define CELL_PER_ENB 8
#define UE_PER_ENB 128
#define RAB_PER_UE 16
#define SIZE_OF_ENB_POOL 128
#define SIZE_OF_UE_POOL (SIZE_OF_ENB_POOL * UE_PER_ENB)
#define SIZE_OF_RAB_POOL (SIZE_OF_UE_POOL * RAB_PER_UE)
#define S1_SCTP_PORT 36412
#define GTP_C_UDP_PORT 2123
#define GTP_U_UDP_PORT 2152
@ -37,7 +45,7 @@ status_t mme_ctx_init()
memset(&self, 0, sizeof(mme_ctx_t));
self.enb_local_addr = inet_addr("127.0.0.1");
self.enb_s1_port = S1_SCTP_PORT;
self.enb_s1ap_port = S1_SCTP_PORT;
self.plmn_id.mnc_len = 2;
self.plmn_id.mcc = 1; /* 001 */
@ -84,17 +92,15 @@ mme_ctx_t* mme_self()
enb_ctx_t* mme_ctx_enb_add()
{
enb_ctx_t *enb = NULL;
/* Allocate new eNB context */
pool_alloc_node(&enb_pool, &enb);
d_assert(enb, return NULL, "eNB context allocation failed");
d_assert(enb, return NULL, "Null param");
/* Initialize eNB context */
memset(enb, 0, sizeof(enb_ctx_t));
/* Add new eNB context to list */
list_init(&enb->ue_list);
list_append(&g_enb_list, enb);
return enb;
@ -104,6 +110,8 @@ status_t mme_ctx_enb_remove(enb_ctx_t *enb)
{
d_assert(enb, return CORE_ERROR, "Null param");
mme_ctx_ue_remove_all(enb);
list_remove(&g_enb_list, enb);
pool_free_node(&enb_pool, enb);
@ -114,10 +122,10 @@ status_t mme_ctx_enb_remove_all()
{
enb_ctx_t *enb = NULL, *next_enb = NULL;
enb = list_first(&g_enb_list);
enb = mme_ctx_enb_first();
while (enb)
{
next_enb = list_next(enb);
next_enb = mme_ctx_enb_next(enb);
mme_ctx_enb_remove(enb);
@ -131,26 +139,26 @@ enb_ctx_t* mme_ctx_enb_find_by_sock(net_sock_t *sock)
{
enb_ctx_t *enb = NULL;
enb = list_first(&g_enb_list);
enb = mme_ctx_enb_first();
while (enb)
{
if (sock == enb->s1_sock)
if (sock == enb->s1ap_sock)
break;
enb = list_next(enb);
enb = mme_ctx_enb_next(enb);
}
return enb;
}
enb_ctx_t* mme_ctx_enb_find_by_id(c_uint32_t id)
enb_ctx_t* mme_ctx_enb_find_by_enb_id(c_uint32_t enb_id)
{
enb_ctx_t *enb = NULL;
enb = list_first(&g_enb_list);
while (enb)
{
if (id == enb->id)
if (enb_id == enb->enb_id)
break;
enb = list_next(enb);
@ -168,3 +176,152 @@ enb_ctx_t* mme_ctx_enb_next(enb_ctx_t *enb)
{
return list_next(enb);
}
ue_ctx_t* mme_ctx_ue_add(enb_ctx_t *enb)
{
ue_ctx_t *ue = NULL;
d_assert(enb, return NULL, "Null param");
pool_alloc_node(&ue_pool, &ue);
d_assert(ue, return NULL, "Null param");
memset(ue, 0, sizeof(ue_ctx_t));
ue->enb = enb;
list_init(&ue->rab_list);
list_append(&enb->ue_list, ue);
return ue;
}
status_t mme_ctx_ue_remove(ue_ctx_t *ue)
{
d_assert(ue, return CORE_ERROR, "Null param");
d_assert(ue->enb, return CORE_ERROR, "Null param");
mme_ctx_rab_remove_all(ue);
list_remove(&ue->enb->ue_list, ue);
pool_free_node(&ue_pool, ue);
return CORE_OK;
}
status_t mme_ctx_ue_remove_all(enb_ctx_t *enb)
{
ue_ctx_t *ue = NULL, *next_ue = NULL;
ue = mme_ctx_ue_first(enb);
while (ue)
{
next_ue = mme_ctx_ue_next(ue);
mme_ctx_ue_remove(ue);
ue = next_ue;
}
return CORE_OK;
}
ue_ctx_t* mme_ctx_ue_find_by_enb_ue_s1ap_id(
enb_ctx_t *enb, c_uint32_t enb_ue_s1ap_id)
{
ue_ctx_t *ue = NULL;
ue = mme_ctx_ue_first(enb);
while (ue)
{
if (enb_ue_s1ap_id == ue->enb_ue_s1ap_id)
break;
ue = mme_ctx_ue_next(ue);
}
return ue;
}
ue_ctx_t* mme_ctx_ue_first(enb_ctx_t *enb)
{
return list_first(&enb->ue_list);
}
ue_ctx_t* mme_ctx_ue_next(ue_ctx_t *ue)
{
return list_next(ue);
}
rab_ctx_t* mme_ctx_rab_add(ue_ctx_t *ue)
{
rab_ctx_t *rab = NULL;
d_assert(ue, return NULL, "Null param");
pool_alloc_node(&rab_pool, &rab);
d_assert(rab, return NULL, "Null param");
memset(rab, 0, sizeof(rab_ctx_t));
rab->ue = ue;
list_append(&ue->rab_list, rab);
return rab;
}
status_t mme_ctx_rab_remove(rab_ctx_t *rab)
{
d_assert(rab, return CORE_ERROR, "Null param");
d_assert(rab->ue, return CORE_ERROR, "Null param");
list_remove(&rab->ue->rab_list, rab);
pool_free_node(&rab_pool, rab);
return CORE_OK;
}
status_t mme_ctx_rab_remove_all(ue_ctx_t *ue)
{
rab_ctx_t *rab = NULL, *next_rab = NULL;
rab = mme_ctx_rab_first(ue);
while (rab)
{
next_rab = mme_ctx_rab_next(rab);
mme_ctx_rab_remove(rab);
rab = next_rab;
}
return CORE_OK;
}
rab_ctx_t* mme_ctx_rab_find_by_e_rab_id(
ue_ctx_t *ue, c_uint32_t e_rab_id)
{
rab_ctx_t *rab = NULL;
rab = mme_ctx_rab_first(ue);
while (rab)
{
if (e_rab_id == rab->e_rab_id)
break;
rab = mme_ctx_rab_next(rab);
}
return rab;
}
rab_ctx_t* mme_ctx_rab_first(ue_ctx_t *ue)
{
return list_first(&ue->rab_list);
}
rab_ctx_t* mme_ctx_rab_next(rab_ctx_t *rab)
{
return list_next(rab);
}

View File

@ -14,16 +14,9 @@ extern "C" {
#define MAX_PLMN_ID 6
#define GRP_PER_MME 256 /* According to spec it is 65535 */
#define CODE_PER_MME 256 /* According to spec it is 256*/
#define CELL_PER_ENB 8
#define UE_PER_ENB 128
#define RAB_PER_UE 16
#define SIZE_OF_ENB_POOL 128
#define SIZE_OF_UE_POOL (SIZE_OF_ENB_POOL * UE_PER_ENB)
#define SIZE_OF_RAB_POOL (SIZE_OF_UE_POOL * RAB_PER_UE)
#define CODE_PER_MME 256 /* According to spec it is 256 */
typedef list_t ue_list_t;
typedef list_t rab_list_t;
typedef struct _served_gummei {
@ -36,11 +29,9 @@ typedef struct _served_gummei {
c_uint8_t mme_code[CODE_PER_MME];
} srvd_gummei_t;
/**
* This structure represents HypcerCell */
typedef struct _mme_ctx_t {
net_sock_t *enb_s1_sock;
c_uint16_t enb_s1_port;
net_sock_t *enb_s1ap_sock;
c_uint16_t enb_s1ap_port;
c_uint32_t enb_local_addr; /** Network byte order */
plmn_id_t plmn_id;
@ -54,29 +45,27 @@ typedef struct _mme_ctx_t {
c_uint8_t relative_capacity;
} mme_ctx_t;
/**
* This structure represents eNB */
typedef struct _enb_ctx_t {
lnode_t node; /**< A node of list_t */
enb_s1_sm_t s1_sm; /**< eNB S1 state machine */
net_sock_t *s1_sock;
c_uint32_t enb_id; /** eNB_ID received from eNB */
enb_s1ap_sm_t s1ap_sm;
net_sock_t *s1ap_sock;
ue_list_t ue_list;
c_uint32_t id;
} enb_ctx_t;
/**
* This structure represents UE-S1 */
typedef struct _ue_ctx_t {
lnode_t node; /**< A node of list_t */
c_uint32_t enb_id; /** eNB-UE-S1AP-ID received from eNB */
c_uint32_t mme_id; /** MME-UE-S1AP-ID received from MME */
c_uint32_t enb_ue_s1ap_id; /** eNB-UE-S1AP-ID received from eNB */
c_uint32_t mme_ue_s1ap_id; /** MME-UE-S1AP-ID received from MME */
rab_list_t rab_list;
enb_ctx_t *enb;
mme_ctx_t *mme;
} ue_ctx_t;
/**
@ -84,7 +73,7 @@ typedef struct _ue_ctx_t {
typedef struct _rab_ctx_t {
lnode_t node; /**< A node of list_t */
c_uint32_t id;
c_uint32_t e_rab_id;
ue_ctx_t *ue;
} rab_ctx_t;
@ -98,10 +87,25 @@ CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_add(void);
CORE_DECLARE(status_t) mme_ctx_enb_remove(enb_ctx_t *enb);
CORE_DECLARE(status_t) mme_ctx_enb_remove_all(void);
CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_find_by_sock(net_sock_t *sock);
CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_find_by_id(c_uint32_t id);
CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_find_by_enb_id(c_uint32_t enb_id);
CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_first(void);
CORE_DECLARE(enb_ctx_t*) mme_ctx_enb_next(enb_ctx_t *enb);
#define self() mme_self()
CORE_DECLARE(ue_ctx_t*) mme_ctx_ue_add(enb_ctx_t *enb);
CORE_DECLARE(status_t) mme_ctx_ue_remove(ue_ctx_t *ue);
CORE_DECLARE(status_t) mme_ctx_ue_remove_all(enb_ctx_t *enb);
CORE_DECLARE(ue_ctx_t*) mme_ctx_ue_find_by_enb_ue_s1ap_id(
enb_ctx_t *enb, c_uint32_t enb_ue_s1ap_id);
CORE_DECLARE(ue_ctx_t*) mme_ctx_ue_first(enb_ctx_t *enb);
CORE_DECLARE(ue_ctx_t*) mme_ctx_ue_next(ue_ctx_t *ue);
CORE_DECLARE(rab_ctx_t*) mme_ctx_rab_add(ue_ctx_t *enb);
CORE_DECLARE(status_t) mme_ctx_rab_remove(rab_ctx_t *ue);
CORE_DECLARE(status_t) mme_ctx_rab_remove_all(ue_ctx_t *enb);
CORE_DECLARE(rab_ctx_t*) mme_ctx_rab_find_by_e_rab_id(
ue_ctx_t *ue, c_uint32_t e_rab_id);
CORE_DECLARE(rab_ctx_t*) mme_ctx_rab_first(ue_ctx_t *enb);
CORE_DECLARE(rab_ctx_t*) mme_ctx_rab_next(rab_ctx_t *ue);
#ifdef __cplusplus
}

View File

@ -17,7 +17,7 @@
status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message *message);
void enb_s1ap_state_initial(enb_s1_sm_t *s, event_t *e)
void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
@ -26,14 +26,14 @@ void enb_s1ap_state_initial(enb_s1_sm_t *s, event_t *e)
FSM_TRAN(s, &enb_s1ap_state_operational);
}
void enb_s1ap_state_final(enb_s1_sm_t *s, event_t *e)
void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
sm_trace(1, e);
}
void enb_s1ap_state_operational(enb_s1_sm_t *s, event_t *e)
void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
@ -121,7 +121,7 @@ void enb_s1ap_state_operational(enb_s1_sm_t *s, event_t *e)
}
}
void enb_s1ap_state_exception(enb_s1_sm_t *s, event_t *e)
void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
@ -156,7 +156,7 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message *message)
c_uint32_t enb_id;
d_assert(enb, return CORE_ERROR, "Null param");
d_assert(enb->s1_sock, return CORE_ERROR, "Null param");
d_assert(enb->s1ap_sock, return CORE_ERROR, "Null param");
d_assert(message, return CORE_ERROR, "Null param");
ies = &message->s1ap_S1SetupRequestIEs;
@ -165,11 +165,11 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message *message)
s1ap_ENB_ID_to_uint32(&ies->global_ENB_ID.eNB_ID, &enb_id);
#if 0 /* FIXME : does it needed? */
if (mme_ctx_enb_find_by_id(enb_id))
if (mme_ctx_enb_find_by_enb_id(enb_id))
{
S1ap_Cause_t cause;
d_error("eNB-id[0x%x] duplicated from [%s]", enb_id,
INET_NTOP(&enb->s1_sock->remote.sin_addr.s_addr, buf));
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf));
cause.present = S1ap_Cause_PR_protocol;
cause.choice.protocol =
@ -180,9 +180,9 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message *message)
#endif
{
d_info("eNB-id[0x%x] sends S1-Setup-Request from [%s]", enb_id,
INET_NTOP(&enb->s1_sock->remote.sin_addr.s_addr, buf));
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf));
enb->id = enb_id;
enb->enb_id = enb_id;
rv = s1ap_build_setup_rsp(&sendbuf);
}

View File

@ -72,14 +72,14 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
enb_ctx_t *enb = mme_ctx_enb_add();
d_assert(enb, break, "Null param");
enb->s1_sock = sock;
enb->s1ap_sock = sock;
fsm_create((fsm_t*)&enb->s1_sm,
fsm_create((fsm_t*)&enb->s1ap_sm,
enb_s1ap_state_initial, enb_s1ap_state_final);
enb->s1_sm.ctx = enb;
enb->s1_sm.queue_id = s->queue_id;
enb->s1_sm.tm_service = s->tm_service;
fsm_init((fsm_t*)&enb->s1_sm, 0);
enb->s1ap_sm.ctx = enb;
enb->s1ap_sm.queue_id = s->queue_id;
enb->s1ap_sm.tm_service = s->tm_service;
fsm_init((fsm_t*)&enb->s1ap_sm, 0);
}
else
{
@ -99,7 +99,8 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
enb_ctx_t *enb = mme_ctx_enb_find_by_sock(sock);
if (enb)
{
fsm_dispatch((fsm_t*)&enb->s1_sm, (fsm_event_t*)e);
d_assert(FSM_STATE(&enb->s1ap_sm), break, "Null param");
fsm_dispatch((fsm_t*)&enb->s1ap_sm, (fsm_event_t*)e);
}
else
{
@ -120,17 +121,16 @@ void mme_state_operational(mme_sm_t *s, event_t *e)
if (enb)
{
/* Remove eNB S1 state machine if exist */
if (FSM_STATE(&enb->s1_sm))
{
fsm_final((fsm_t*)&enb->s1_sm, 0);
fsm_clear((fsm_t*)&enb->s1_sm);
}
d_assert(FSM_STATE(&enb->s1ap_sm), break, "Null param");
fsm_final((fsm_t*)&enb->s1ap_sm, 0);
fsm_clear((fsm_t*)&enb->s1ap_sm);
net_unregister_sock(sock);
net_close(sock);
mme_ctx_enb_remove(enb);
d_info("eNB-S1[%x] connection refused!!!", enb->id);
d_info("eNB-S1[%x] connection refused!!!", enb->enb_id);
}
else
{

View File

@ -16,30 +16,30 @@ status_t s1ap_open(msgq_id queue_id)
char buf[INET_ADDRSTRLEN];
int rc;
rc = net_listen_with_addr(&mme_self()->enb_s1_sock,
SOCK_STREAM, IPPROTO_SCTP, mme_self()->enb_s1_port,
rc = net_listen_with_addr(&mme_self()->enb_s1ap_sock,
SOCK_STREAM, IPPROTO_SCTP, mme_self()->enb_s1ap_port,
mme_self()->enb_local_addr);
if (rc != 0)
{
d_error("Can't establish S1-ENB(port:%d) path(%d:%s)",
mme_self()->enb_s1_port, errno, strerror(errno));
mme_self()->enb_s1_sock = NULL;
mme_self()->enb_s1ap_port, errno, strerror(errno));
mme_self()->enb_s1ap_sock = NULL;
return CORE_ERROR;
}
rc = net_register_sock(
mme_self()->enb_s1_sock, _s1ap_accept_cb, (void *)queue_id);
mme_self()->enb_s1ap_sock, _s1ap_accept_cb, (void *)queue_id);
if (rc != 0)
{
d_error("Can't establish S1-ENB path(%d:%s)",
errno, strerror(errno));
net_close(mme_self()->enb_s1_sock);
mme_self()->enb_s1_sock = NULL;
net_close(mme_self()->enb_s1ap_sock);
mme_self()->enb_s1ap_sock = NULL;
return CORE_ERROR;
}
d_trace(1, "s1_enb_listen() %s:%d\n",
INET_NTOP(&mme_self()->enb_local_addr, buf), mme_self()->enb_s1_port);
INET_NTOP(&mme_self()->enb_local_addr, buf), mme_self()->enb_s1ap_port);
return CORE_OK;
}
@ -47,11 +47,11 @@ status_t s1ap_open(msgq_id queue_id)
status_t s1ap_close()
{
d_assert(mme_self(), return CORE_ERROR, "Null param");
d_assert(mme_self()->enb_s1_sock != NULL, return CORE_ERROR,
d_assert(mme_self()->enb_s1ap_sock != NULL, return CORE_ERROR,
"S1-ENB path already opened");
net_unregister_sock(mme_self()->enb_s1_sock);
net_close(mme_self()->enb_s1_sock);
mme_self()->enb_s1_sock = NULL;
net_unregister_sock(mme_self()->enb_s1ap_sock);
net_close(mme_self()->enb_s1ap_sock);
mme_self()->enb_s1ap_sock = NULL;
return CORE_OK;
}
@ -191,7 +191,7 @@ status_t s1ap_send_to_enb(enb_ctx_t *enb, pkbuf_t *pkb)
{
d_assert(enb, return CORE_ERROR, "Null param");
d_assert(pkb, return CORE_ERROR, "Null param");
d_assert(enb->s1_sock, return CORE_ERROR, "No S1 path with ENB");
d_assert(enb->s1ap_sock, return CORE_ERROR, "No S1 path with ENB");
return s1ap_send(enb->s1_sock, pkb);
return s1ap_send(enb->s1ap_sock, pkb);
}

View File

@ -24,19 +24,19 @@ void mme_state_final(mme_sm_t *s, event_t *e);
void mme_state_operational(mme_sm_t *s, event_t *e);
void mme_state_exception(mme_sm_t *s, event_t *e);
typedef struct _enb_s1_sm_t {
typedef struct _enb_s1ap_sm_t {
fsm_t fsm;
void *ctx;
msgq_id queue_id;
tm_service_t tm_service;
} enb_s1_sm_t;
} enb_s1ap_sm_t;
void enb_s1ap_state_initial(enb_s1_sm_t *s, event_t *e);
void enb_s1ap_state_final(enb_s1_sm_t *s, event_t *e);
void enb_s1ap_state_operational(enb_s1_sm_t *s, event_t *e);
void enb_s1ap_state_exception(enb_s1_sm_t *s, event_t *e);
void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e);
void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e);
void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e);
void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e);
#define sm_print(__pe) \
d_print("%s(): %s\n", __func__, event_get_name(__pe))

View File

@ -20,7 +20,7 @@ net_sock_t *enb_net_open(void)
if (!mme) return NULL;
rv = net_open_with_addr(&sock, mme->enb_local_addr, "127.0.0.1", 0,
mme->enb_s1_port, SOCK_SEQPACKET, IPPROTO_SCTP, 0);
mme->enb_s1ap_port, SOCK_SEQPACKET, IPPROTO_SCTP, 0);
if (rv != CORE_OK) return NULL;
return sock;