diff --git a/lib/core/ogs-pkbuf.h b/lib/core/ogs-pkbuf.h index d6396615f..75abcd34b 100644 --- a/lib/core/ogs-pkbuf.h +++ b/lib/core/ogs-pkbuf.h @@ -37,6 +37,11 @@ typedef struct ogs_cluster_s { typedef struct ogs_pkbuf_pool_s ogs_pkbuf_pool_t; typedef struct ogs_pkbuf_s { + ogs_lnode_t lnode; + + /* Currently it is used in SCTP stream number and PPID. */ + uint64_t param[2]; + ogs_cluster_t *cluster; unsigned int len; diff --git a/lib/core/ogs-poll.c b/lib/core/ogs-poll.c index 3b39344c7..e0a4de4d0 100644 --- a/lib/core/ogs-poll.c +++ b/lib/core/ogs-poll.c @@ -124,6 +124,12 @@ void ogs_pollset_remove(ogs_poll_t *poll) ogs_pool_free(&pollset->pool, poll); } +ogs_poll_t *ogs_pollset_cycle(ogs_pollset_t *pollset, ogs_poll_t *poll) +{ + ogs_assert(pollset); + return ogs_pool_cycle(&pollset->pool, poll); +} + void *ogs_pollset_self_handler_data(void) { return &self_handler_data; diff --git a/lib/core/ogs-poll.h b/lib/core/ogs-poll.h index e4261e628..5251b1312 100644 --- a/lib/core/ogs-poll.h +++ b/lib/core/ogs-poll.h @@ -40,6 +40,7 @@ ogs_poll_t *ogs_pollset_add(ogs_pollset_t *pollset, short when, ogs_socket_t fd, ogs_poll_handler_f handler, void *data); void ogs_pollset_remove(ogs_poll_t *poll); +ogs_poll_t *ogs_pollset_cycle(ogs_pollset_t *pollset, ogs_poll_t *poll); void *ogs_pollset_self_handler_data(void); typedef struct ogs_pollset_actions_s { diff --git a/lib/meson.build b/lib/meson.build index 98e0c4a93..ba2920ea9 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -20,9 +20,9 @@ libinc = include_directories('.') subdir('core') subdir('ipfw') subdir('crypt') +subdir('app') subdir('sctp') subdir('dbi') -subdir('app') subdir('diameter') subdir('asn1c') subdir('ngap') diff --git a/lib/sctp/meson.build b/lib/sctp/meson.build index fe62680fa..7a980bbdb 100644 --- a/lib/sctp/meson.build +++ b/lib/sctp/meson.build @@ -59,10 +59,10 @@ libsctp = library('ogssctp', version : libogslib_version, c_args : '-DOGS_SCTP_COMPILATION', include_directories : [libsctp_inc, libinc], - dependencies : [libcore_dep, sctp_dep], + dependencies : [libcore_dep, libapp_dep, sctp_dep], install : true) libsctp_dep = declare_dependency( link_with : libsctp, include_directories : [libsctp_inc, libinc], - dependencies : [libcore_dep, sctp_dep]) + dependencies : [libcore_dep, libapp_dep, sctp_dep]) diff --git a/lib/sctp/ogs-sctp.c b/lib/sctp/ogs-sctp.c index 74ec9fcd7..02640df7b 100644 --- a/lib/sctp/ogs-sctp.c +++ b/lib/sctp/ogs-sctp.c @@ -18,9 +18,12 @@ */ #include "ogs-sctp.h" +#include "ogs-app.h" int __ogs_sctp_domain; +static void sctp_write_callback(short when, ogs_socket_t fd, void *data); + void ogs_sctp_set_option(ogs_sockopt_t *option, ogs_socknode_t *node) { ogs_assert(option); @@ -99,3 +102,88 @@ int ogs_sctp_recvdata(ogs_sock_t *sock, void *msg, size_t len, return size; } + +int ogs_sctp_senddata(ogs_sock_t *sock, + ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr) +{ + int sent; + + ogs_assert(sock); + ogs_assert(pkbuf); + + sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, addr, + ogs_sctp_ppid_in_pkbuf(pkbuf), ogs_sctp_stream_no_in_pkbuf(pkbuf)); + if (sent < 0 || sent != pkbuf->len) { + ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, + "ogs_sctp_senddata(len:%d,ssn:%d)", + pkbuf->len, (int)ogs_sctp_stream_no_in_pkbuf(pkbuf)); + ogs_pkbuf_free(pkbuf); + return OGS_ERROR; + } + + ogs_pkbuf_free(pkbuf); + return OGS_OK; +} + +void ogs_sctp_write_to_buffer(ogs_sctp_sock_t *sctp, ogs_pkbuf_t *pkbuf) +{ + ogs_poll_t *poll = NULL; + + ogs_assert(sctp); + ogs_assert(pkbuf); + + ogs_list_add(&sctp->write_queue, pkbuf); + + poll = ogs_pollset_cycle(ogs_app()->pollset, sctp->poll.write); + if (!poll) { + ogs_assert(sctp->sock); + sctp->poll.write = ogs_pollset_add(ogs_app()->pollset, + OGS_POLLOUT, sctp->sock->fd, sctp_write_callback, sctp); + } +} + +static void sctp_write_callback(short when, ogs_socket_t fd, void *data) +{ + ogs_sctp_sock_t *sctp = data; + ogs_pkbuf_t *pkbuf = NULL; + + ogs_assert(sctp); + if (ogs_list_empty(&sctp->write_queue) == true) { + ogs_assert(sctp->poll.write); + ogs_pollset_remove(sctp->poll.write); + return; + } + + pkbuf = ogs_list_first(&sctp->write_queue); + ogs_assert(pkbuf); + ogs_list_remove(&sctp->write_queue, pkbuf); + + ogs_assert(sctp->sock); + ogs_sctp_senddata(sctp->sock, pkbuf, NULL); +} + +void ogs_sctp_flush_and_destroy(ogs_sctp_sock_t *sctp) +{ + ogs_poll_t *poll = NULL; + ogs_pkbuf_t *pkbuf = NULL, *next_pkbuf = NULL; + + ogs_assert(sctp); + + ogs_assert(sctp->addr); + ogs_free(sctp->addr); + + if (sctp->type == SOCK_STREAM) { + poll = ogs_pollset_cycle(ogs_app()->pollset, sctp->poll.read); + ogs_assert(poll); + ogs_pollset_remove(poll); + + poll = ogs_pollset_cycle(ogs_app()->pollset, sctp->poll.write); + if (poll) + ogs_pollset_remove(poll); + + ogs_sctp_destroy(sctp->sock); + + ogs_list_for_each_safe(&sctp->write_queue, next_pkbuf, pkbuf) + ogs_pkbuf_free(pkbuf); + } +} diff --git a/lib/sctp/ogs-sctp.h b/lib/sctp/ogs-sctp.h index dd280a951..639d88da6 100644 --- a/lib/sctp/ogs-sctp.h +++ b/lib/sctp/ogs-sctp.h @@ -48,6 +48,9 @@ extern int __ogs_sctp_domain; #define OGS_SCTP_SGSAP_PPID 0 #define OGS_SCTP_NGAP_PPID 60 +#define ogs_sctp_ppid_in_pkbuf(__pkBUF) (__pkBUF)->param[0] +#define ogs_sctp_stream_no_in_pkbuf(__pkBUF) (__pkBUF)->param[1] + #if HAVE_USRSCTP #undef MSG_NOTIFICATION @@ -79,6 +82,20 @@ ogs_sock_t *ogs_sctp_accept(ogs_sock_t *sock); #define DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30 +typedef struct ogs_sctp_sock_s { + int type; /* SOCK_STREAM or SOCK_SEQPACKET */ + + ogs_sock_t *sock; /* Socket */ + ogs_sockaddr_t *addr; /* Address */ + + struct { + ogs_poll_t *read; /* Read Poll */ + ogs_poll_t *write; /* Write Poll */ + } poll; + + ogs_list_t write_queue; /* Write Queue for Sending S1AP message */ +} ogs_sctp_sock_t; + typedef struct ogs_sctp_info_s { uint32_t ppid; uint16_t stream_no; @@ -107,6 +124,11 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len, int ogs_sctp_recvdata(ogs_sock_t *sock, void *msg, size_t len, ogs_sockaddr_t *from, ogs_sctp_info_t *sinfo); +int ogs_sctp_senddata(ogs_sock_t *sock, + ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr); +void ogs_sctp_write_to_buffer(ogs_sctp_sock_t *sctp, ogs_pkbuf_t *pkbuf); +void ogs_sctp_flush_and_destroy(ogs_sctp_sock_t *sctp); + #ifdef __cplusplus } #endif diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index acc6634e2..1123a526d 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -589,7 +589,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) ogs_min(max_num_of_ostreams, gnb->max_num_of_ostreams); ogs_debug("gNB-N1 SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]", - OGS_ADDR(gnb->addr, buf), gnb->max_num_of_ostreams); + OGS_ADDR(gnb->sctp.addr, buf), gnb->max_num_of_ostreams); break; diff --git a/src/amf/context.c b/src/amf/context.c index 2e285149e..ee2b78e08 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -833,9 +833,15 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr) ogs_assert(gnb); memset(gnb, 0, sizeof *gnb); - gnb->sock = sock; - gnb->addr = addr; - gnb->sock_type = amf_gnb_sock_type(gnb->sock); + gnb->sctp.sock = sock; + gnb->sctp.addr = addr; + gnb->sctp.type = amf_gnb_sock_type(gnb->sctp.sock); + + if (gnb->sctp.type == SOCK_STREAM) { + gnb->sctp.poll.read = ogs_pollset_add(ogs_app()->pollset, + OGS_POLLIN, sock->fd, ngap_recv_upcall, sock); + ogs_assert(gnb->sctp.poll.read); + } gnb->max_num_of_ostreams = DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS; gnb->ostream_id = 0; @@ -847,13 +853,8 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr) ogs_list_init(&gnb->ran_ue_list); - if (gnb->sock_type == SOCK_STREAM) { - gnb->poll = ogs_pollset_add(ogs_app()->pollset, - OGS_POLLIN, sock->fd, ngap_recv_upcall, sock); - ogs_assert(gnb->poll); - } - - ogs_hash_set(self.gnb_addr_hash, gnb->addr, sizeof(ogs_sockaddr_t), gnb); + ogs_hash_set(self.gnb_addr_hash, + gnb->sctp.addr, sizeof(ogs_sockaddr_t), gnb); memset(&e, 0, sizeof(e)); e.gnb = gnb; @@ -873,7 +874,7 @@ int amf_gnb_remove(amf_gnb_t *gnb) amf_event_t e; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_list_remove(&self.gnb_list, gnb); @@ -882,15 +883,11 @@ int amf_gnb_remove(amf_gnb_t *gnb) ogs_fsm_fini(&gnb->sm, &e); ogs_fsm_delete(&gnb->sm); - ogs_hash_set(self.gnb_addr_hash, gnb->addr, sizeof(ogs_sockaddr_t), NULL); + ogs_hash_set(self.gnb_addr_hash, + gnb->sctp.addr, sizeof(ogs_sockaddr_t), NULL); ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL); - if (gnb->sock_type == SOCK_STREAM) { - ogs_pollset_remove(gnb->poll); - ogs_sctp_destroy(gnb->sock); - } - - ogs_free(gnb->addr); + ogs_sctp_flush_and_destroy(&gnb->sctp); ogs_pool_free(&amf_gnb_pool, gnb); diff --git a/src/amf/context.h b/src/amf/context.h index 710ed20aa..169a8a68a 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -120,10 +120,7 @@ typedef struct amf_gnb_s { ogs_fsm_t sm; /* A state machine */ uint32_t gnb_id; /* gNB_ID received from gNB */ - int sock_type; /* SOCK_STREAM or SOCK_SEQPACKET */ - ogs_sock_t *sock; /* gNB NGAP Socket */ - ogs_sockaddr_t *addr; /* gNB NGAP Address */ - ogs_poll_t *poll; /* gNB NGAP Poll */ + ogs_sctp_sock_t sctp; /* SCTP socket */ struct { bool ng_setup_success; /* gNB NGAP Setup complete successfuly */ @@ -132,7 +129,6 @@ typedef struct amf_gnb_s { uint16_t max_num_of_ostreams;/* SCTP Max num of outbound streams */ uint16_t ostream_id; /* gnb_ostream_id generator */ - uint8_t num_of_supported_ta_list; struct { ogs_uint24_t tac; diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 17a2d6b59..edbe3d3bc 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -116,7 +116,7 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) uint32_t gnb_id; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -169,7 +169,7 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) } ogs_ngap_GNB_ID_to_uint32(&globalGNB_ID->gNB_ID, &gnb_id); - ogs_debug(" IP[%s] GNB_ID[0x%x]", OGS_ADDR(gnb->addr, buf), gnb_id); + ogs_debug(" IP[%s] GNB_ID[0x%x]", OGS_ADDR(gnb->sctp.addr, buf), gnb_id); if (PagingDRX) ogs_debug(" PagingDRX[%ld]", *PagingDRX); @@ -336,7 +336,7 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message) NGAP_FiveG_S_TMSI_t *FiveG_S_TMSI = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -367,7 +367,8 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message) } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!RAN_UE_NGAP_ID) { ogs_error("No RAN_UE_NGAP_ID"); @@ -495,7 +496,7 @@ void ngap_handle_uplink_nas_transport( NGAP_NAS_PDU_t *NAS_PDU = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -522,7 +523,8 @@ void ngap_handle_uplink_nas_transport( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -581,7 +583,7 @@ void ngap_handle_ue_radio_capability_info_indication( NGAP_UERadioCapability_t *UERadioCapability = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -610,7 +612,8 @@ void ngap_handle_ue_radio_capability_info_indication( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -676,7 +679,7 @@ void ngap_handle_initial_context_setup_response( OCTET_STRING_t *transfer = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -705,7 +708,8 @@ void ngap_handle_initial_context_setup_response( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -823,7 +827,7 @@ void ngap_handle_initial_context_setup_failure( NGAP_Cause_t *Cause = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); unsuccessfulOutcome = message->choice.unsuccessfulOutcome; @@ -851,7 +855,8 @@ void ngap_handle_initial_context_setup_failure( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -943,7 +948,7 @@ void ngap_handle_ue_context_release_request( NGAP_Cause_t *Cause = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -974,7 +979,8 @@ void ngap_handle_ue_context_release_request( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -1099,7 +1105,7 @@ void ngap_handle_ue_context_release_complete( NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -1124,7 +1130,8 @@ void ngap_handle_ue_context_release_complete( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -1234,7 +1241,7 @@ void ngap_handle_pdu_session_resource_setup_response( OCTET_STRING_t *transfer = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -1264,7 +1271,8 @@ void ngap_handle_pdu_session_resource_setup_response( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -1398,7 +1406,7 @@ void ngap_handle_pdu_session_resource_release_response( OCTET_STRING_t *transfer = NULL; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -1428,7 +1436,8 @@ void ngap_handle_pdu_session_resource_release_response( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); @@ -1573,7 +1582,7 @@ void ngap_handle_path_switch_request( amf_nsmf_pdu_session_update_sm_context_param_t param; ogs_assert(gnb); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1607,7 +1616,8 @@ void ngap_handle_path_switch_request( } } - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); if (!AMF_UE_NGAP_ID) { ogs_error("No AMF_UE_NGAP_ID"); diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c index aedb72b3d..aa0e25ee5 100644 --- a/src/amf/ngap-path.c +++ b/src/amf/ngap-path.c @@ -46,40 +46,23 @@ void ngap_close() ogs_socknode_remove_all(&amf_self()->ngap_list6); } -int ngap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, - ogs_sockaddr_t *addr, uint16_t stream_no) -{ - int sent; - - ogs_assert(sock); - ogs_assert(pkbuf); - - sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, - addr, OGS_SCTP_NGAP_PPID, stream_no); - if (sent < 0 || sent != pkbuf->len) { - ogs_error("ogs_sctp_sendmsg(len:%d,ssn:%d) error (%d:%s)", - pkbuf->len, stream_no, errno, strerror(errno)); - ogs_pkbuf_free(pkbuf); - return OGS_ERROR; - } - - ogs_pkbuf_free(pkbuf); - return OGS_OK; -} - int ngap_send_to_gnb(amf_gnb_t *gnb, ogs_pkbuf_t *pkbuf, uint16_t stream_no) { char buf[OGS_ADDRSTRLEN]; ogs_assert(gnb); ogs_assert(pkbuf); - ogs_assert(gnb->sock); + ogs_assert(gnb->sctp.sock); - ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id); + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); - return ngap_send(gnb->sock, pkbuf, - gnb->sock_type == SOCK_STREAM ? NULL : gnb->addr, - stream_no); + if (gnb->sctp.type == SOCK_STREAM) { + ogs_sctp_write_to_buffer(&gnb->sctp, pkbuf); + return OGS_OK; + } else { + return ogs_sctp_senddata(gnb->sctp.sock, pkbuf, gnb->sctp.addr); + } } int ngap_send_to_ran_ue(ran_ue_t *ran_ue, ogs_pkbuf_t *pkbuf) diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 3cec13bba..5f69493be 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -1879,9 +1879,17 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr) ogs_assert(enb); memset(enb, 0, sizeof *enb); - enb->sock = sock; - enb->addr = addr; - enb->sock_type = mme_enb_sock_type(enb->sock); + enb->sctp.sock = sock; + enb->sctp.addr = addr; + enb->sctp.type = mme_enb_sock_type(enb->sctp.sock); + + if (enb->sctp.type == SOCK_STREAM) { + enb->sctp.poll.read = ogs_pollset_add(ogs_app()->pollset, + OGS_POLLIN, sock->fd, s1ap_recv_upcall, sock); + ogs_assert(enb->sctp.poll.read); + + ogs_list_init(&enb->sctp.write_queue); + } enb->max_num_of_ostreams = DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS; enb->ostream_id = 0; @@ -1893,13 +1901,8 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr) ogs_list_init(&enb->enb_ue_list); - if (enb->sock_type == SOCK_STREAM) { - enb->poll = ogs_pollset_add(ogs_app()->pollset, - OGS_POLLIN, sock->fd, s1ap_recv_upcall, sock); - ogs_assert(enb->poll); - } - - ogs_hash_set(self.enb_addr_hash, enb->addr, sizeof(ogs_sockaddr_t), enb); + ogs_hash_set(self.enb_addr_hash, + enb->sctp.addr, sizeof(ogs_sockaddr_t), enb); memset(&e, 0, sizeof(e)); e.enb = enb; @@ -1919,7 +1922,7 @@ int mme_enb_remove(mme_enb_t *enb) mme_event_t e; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_list_remove(&self.enb_list, enb); @@ -1928,15 +1931,11 @@ int mme_enb_remove(mme_enb_t *enb) ogs_fsm_fini(&enb->sm, &e); ogs_fsm_delete(&enb->sm); - ogs_hash_set(self.enb_addr_hash, enb->addr, sizeof(ogs_sockaddr_t), NULL); + ogs_hash_set(self.enb_addr_hash, + enb->sctp.addr, sizeof(ogs_sockaddr_t), NULL); ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL); - if (enb->sock_type == SOCK_STREAM) { - ogs_pollset_remove(enb->poll); - ogs_sctp_destroy(enb->sock); - } - - ogs_free(enb->addr); + ogs_sctp_flush_and_destroy(&enb->sctp); ogs_pool_free(&mme_enb_pool, enb); diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index aacb6b740..1f1f0bd12 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -27,6 +27,7 @@ #include "ogs-gtp.h" #include "ogs-nas-eps.h" #include "ogs-app.h" +#include "ogs-sctp.h" /* S1AP */ #include "S1AP_Cause.h" @@ -209,10 +210,7 @@ typedef struct mme_enb_s { ogs_fsm_t sm; /* A state machine */ uint32_t enb_id; /* eNB_ID received from eNB */ - int sock_type; /* SOCK_STREAM or SOCK_SEQPACKET */ - ogs_sock_t *sock; /* eNB S1AP Socket */ - ogs_sockaddr_t *addr; /* eNB S1AP Address */ - ogs_poll_t *poll; /* eNB S1AP Poll */ + ogs_sctp_sock_t sctp; /* SCTP socket */ struct { bool s1_setup_success; /* eNB S1AP Setup complete successfuly */ @@ -221,7 +219,6 @@ typedef struct mme_enb_s { uint16_t max_num_of_ostreams;/* SCTP Max num of outbound streams */ uint16_t ostream_id; /* enb_ostream_id generator */ - uint8_t num_of_supported_ta_list; ogs_eps_tai_t supported_ta_list[OGS_MAX_NUM_OF_TAI*OGS_MAX_NUM_OF_BPLMN]; diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index 37ae54afc..f990bfe3a 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -209,7 +209,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) ogs_min(max_num_of_ostreams, enb->max_num_of_ostreams); ogs_debug("eNB-S1 SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]", - OGS_ADDR(enb->addr, buf), enb->max_num_of_ostreams); + OGS_ADDR(enb->sctp.addr, buf), enb->max_num_of_ostreams); break; diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index e21fa03f9..9f748704d 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -82,7 +82,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message) long cause = 0; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -112,7 +112,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message) ogs_assert(Global_ENB_ID); ogs_s1ap_ENB_ID_to_uint32(&Global_ENB_ID->eNB_ID, &enb_id); - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->sctp.addr, buf), enb_id); if (PagingDRX) ogs_debug(" PagingDRX[%ld]", *PagingDRX); @@ -212,7 +212,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message) enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -245,7 +245,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message) } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -359,7 +360,7 @@ void s1ap_handle_uplink_nas_transport( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -383,7 +384,8 @@ void s1ap_handle_uplink_nas_transport( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -426,7 +428,7 @@ void s1ap_handle_ue_capability_info_indication( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -451,7 +453,8 @@ void s1ap_handle_ue_capability_info_indication( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(ENB_UE_S1AP_ID); enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID); @@ -485,7 +488,7 @@ void s1ap_handle_initial_context_setup_response( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -511,7 +514,8 @@ void s1ap_handle_initial_context_setup_response( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -622,7 +626,7 @@ void s1ap_handle_initial_context_setup_failure( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); unsuccessfulOutcome = message->choice.unsuccessfulOutcome; @@ -647,7 +651,8 @@ void s1ap_handle_initial_context_setup_failure( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -709,7 +714,7 @@ void s1ap_handle_ue_context_modification_response( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -731,7 +736,8 @@ void s1ap_handle_ue_context_modification_response( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -777,7 +783,7 @@ void s1ap_handle_ue_context_modification_failure( mme_ue_t *mme_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); unsuccessfulOutcome = message->choice.unsuccessfulOutcome; @@ -802,7 +808,8 @@ void s1ap_handle_ue_context_modification_failure( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -854,7 +861,7 @@ void s1ap_handle_e_rab_setup_response( mme_ue_t *mme_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -879,7 +886,8 @@ void s1ap_handle_e_rab_setup_response( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!ENB_UE_S1AP_ID) { ogs_error("No ENB_UE_S1AP_ID"); @@ -980,7 +988,7 @@ void s1ap_handle_ue_context_release_request( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1008,7 +1016,8 @@ void s1ap_handle_ue_context_release_request( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!MME_UE_S1AP_ID) { ogs_error("No MME_UE_S1AP_ID"); @@ -1067,7 +1076,7 @@ void s1ap_handle_ue_context_release_complete( enb_ue_t *enb_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -1089,7 +1098,8 @@ void s1ap_handle_ue_context_release_complete( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (!MME_UE_S1AP_ID) { ogs_error("No MME_UE_S1AP_ID"); @@ -1204,7 +1214,7 @@ void s1ap_handle_path_switch_request( ogs_pkbuf_t *s1apbuf = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1241,7 +1251,8 @@ void s1ap_handle_path_switch_request( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(EUTRAN_CGI); pLMNidentity = &EUTRAN_CGI->pLMNidentity; @@ -1266,7 +1277,8 @@ void s1ap_handle_path_switch_request( enb_ue = enb_ue_find_by_mme_ue_s1ap_id(*MME_UE_S1AP_ID); if (!enb_ue) { ogs_error("Cannot find UE from sourceMME-UE-S1AP-ID[%d] and eNB[%s:%d]", - (int)*MME_UE_S1AP_ID, OGS_ADDR(enb->addr, buf), enb->enb_id); + (int)*MME_UE_S1AP_ID, + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); s1apbuf = s1ap_build_path_switch_failure( *ENB_UE_S1AP_ID, *MME_UE_S1AP_ID, @@ -1385,7 +1397,7 @@ void s1ap_handle_enb_configuration_transfer( S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1407,7 +1419,8 @@ void s1ap_handle_enb_configuration_transfer( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); if (SONConfigurationTransfer) { S1AP_TargeteNB_ID_t *targeteNB_ID = @@ -1474,7 +1487,7 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message) *Source_ToTarget_TransparentContainer = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1515,7 +1528,8 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message) } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(TargetID); switch (TargetID->present) { @@ -1590,7 +1604,7 @@ void s1ap_handle_handover_request_ack( mme_ue_t *mme_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -1620,7 +1634,8 @@ void s1ap_handle_handover_request_ack( break; } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(MME_UE_S1AP_ID); ogs_assert(ENB_UE_S1AP_ID); @@ -1714,7 +1729,7 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, ogs_s1ap_message_t *message) enb_ue_t *source_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); unsuccessfulOutcome = message->choice.unsuccessfulOutcome; @@ -1737,7 +1752,8 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, ogs_s1ap_message_t *message) } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(MME_UE_S1AP_ID); ogs_assert(Cause); @@ -1778,7 +1794,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, ogs_s1ap_message_t *message) enb_ue_t *target_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1803,7 +1819,8 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, ogs_s1ap_message_t *message) break; } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(MME_UE_S1AP_ID); ogs_assert(ENB_UE_S1AP_ID); @@ -1832,7 +1849,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, ogs_s1ap_message_t *message) ogs_debug("[MME] Handover Cancel : " "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]", source_ue->enb_ue_s1ap_id, - OGS_ADDR(enb->addr, buf), enb->enb_id); + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); } void s1ap_handle_enb_status_transfer(mme_enb_t *enb, ogs_s1ap_message_t *message) @@ -1852,7 +1869,7 @@ void s1ap_handle_enb_status_transfer(mme_enb_t *enb, ogs_s1ap_message_t *message enb_ue_t *source_ue = NULL, *target_ue = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1878,7 +1895,8 @@ void s1ap_handle_enb_status_transfer(mme_enb_t *enb, ogs_s1ap_message_t *message break; } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(MME_UE_S1AP_ID); ogs_assert(ENB_UE_S1AP_ID); @@ -1926,7 +1944,7 @@ void s1ap_handle_handover_notification( mme_bearer_t *bearer = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -1954,7 +1972,8 @@ void s1ap_handle_handover_notification( break; } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(EUTRAN_CGI); pLMNidentity = &EUTRAN_CGI->pLMNidentity; @@ -2050,7 +2069,7 @@ void s1ap_handle_s1_reset( S1AP_UE_associatedLogicalS1_ConnectionListRes_t *partOfS1_Interface = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); initiatingMessage = message->choice.initiatingMessage; @@ -2074,7 +2093,8 @@ void s1ap_handle_s1_reset( } } - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); ogs_assert(Cause); ogs_debug(" Cause[Group:%d Cause:%d]", @@ -2183,7 +2203,7 @@ void s1ap_handle_write_replace_warning_response( S1AP_WriteReplaceWarningResponse_t *WriteReplaceWarningResponse = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -2194,7 +2214,8 @@ void s1ap_handle_write_replace_warning_response( ogs_debug("[MME] Write replace warning response"); - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); } @@ -2207,7 +2228,7 @@ void s1ap_handle_kill_response( S1AP_KillResponse_t *KillResponse = NULL; ogs_assert(enb); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); ogs_assert(message); successfulOutcome = message->choice.successfulOutcome; @@ -2218,5 +2239,6 @@ void s1ap_handle_kill_response( ogs_debug("[MME] Kill response"); - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); } diff --git a/src/mme/s1ap-path.c b/src/mme/s1ap-path.c index 358126b6a..cdba53480 100644 --- a/src/mme/s1ap-path.c +++ b/src/mme/s1ap-path.c @@ -47,40 +47,26 @@ void s1ap_close() ogs_socknode_remove_all(&mme_self()->s1ap_list6); } -int s1ap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, - ogs_sockaddr_t *addr, uint16_t stream_no) -{ - int sent; - - ogs_assert(sock); - ogs_assert(pkbuf); - - sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, - addr, OGS_SCTP_S1AP_PPID, stream_no); - if (sent < 0 || sent != pkbuf->len) { - ogs_error("ogs_sctp_sendmsg(len:%d,ssn:%d) error (%d:%s)", - pkbuf->len, stream_no, errno, strerror(errno)); - ogs_pkbuf_free(pkbuf); - return OGS_ERROR; - } - - ogs_pkbuf_free(pkbuf); - return OGS_OK; -} - int s1ap_send_to_enb(mme_enb_t *enb, ogs_pkbuf_t *pkbuf, uint16_t stream_no) { char buf[OGS_ADDRSTRLEN]; ogs_assert(enb); ogs_assert(pkbuf); - ogs_assert(enb->sock); + ogs_assert(enb->sctp.sock); - ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", + OGS_ADDR(enb->sctp.addr, buf), enb->enb_id); - return s1ap_send(enb->sock, pkbuf, - enb->sock_type == SOCK_STREAM ? NULL : enb->addr, - stream_no); + ogs_sctp_ppid_in_pkbuf(pkbuf) = OGS_SCTP_S1AP_PPID; + ogs_sctp_stream_no_in_pkbuf(pkbuf) = stream_no; + + if (enb->sctp.type == SOCK_STREAM) { + ogs_sctp_write_to_buffer(&enb->sctp, pkbuf); + return OGS_OK; + } else { + return ogs_sctp_senddata(enb->sctp.sock, pkbuf, enb->sctp.addr); + } } int s1ap_send_to_enb_ue(enb_ue_t *enb_ue, ogs_pkbuf_t *pkbuf) diff --git a/src/mme/s1ap-path.h b/src/mme/s1ap-path.h index 2ea5d8ddd..17c80c4a7 100644 --- a/src/mme/s1ap-path.h +++ b/src/mme/s1ap-path.h @@ -36,8 +36,6 @@ void s1ap_close(void); ogs_sock_t *s1ap_server(ogs_socknode_t *node); void s1ap_recv_upcall(short when, ogs_socket_t fd, void *data); -int s1ap_send(ogs_sock_t *sock, - ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no); int s1ap_send_to_enb( mme_enb_t *enb, ogs_pkbuf_t *pkb, uint16_t stream_no);