itti dynamic queue creation, and 64 bits instance id
This commit is contained in:
@@ -29,7 +29,7 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, in
|
||||
MessageDef *message_p;
|
||||
sctp_init_msg_multi_cnf_t *sctp_init_msg_multi_cnf_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_INIT_MSG_MULTI_CNF);
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_INIT_MSG_MULTI_CNF);
|
||||
|
||||
sctp_init_msg_multi_cnf_p = &message_p->ittiMsg.sctp_init_msg_multi_cnf;
|
||||
|
||||
@@ -45,7 +45,7 @@ int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance,
|
||||
MessageDef *message_p;
|
||||
sctp_data_ind_t *sctp_data_ind_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_DATA_IND);
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_DATA_IND);
|
||||
|
||||
sctp_data_ind_p = &message_p->ittiMsg.sctp_data_ind;
|
||||
|
||||
@@ -69,7 +69,7 @@ int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance,
|
||||
MessageDef *message_p;
|
||||
sctp_new_association_resp_t *sctp_new_association_resp_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_RESP);
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_NEW_ASSOCIATION_RESP);
|
||||
|
||||
sctp_new_association_resp_p = &message_p->ittiMsg.sctp_new_association_resp;
|
||||
|
||||
@@ -89,7 +89,7 @@ int sctp_itti_send_association_ind(task_id_t task_id, instance_t instance,
|
||||
MessageDef *message_p;
|
||||
sctp_new_association_ind_t *sctp_new_association_ind_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_IND);
|
||||
message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_NEW_ASSOCIATION_IND);
|
||||
|
||||
sctp_new_association_ind_p = &message_p->ittiMsg.sctp_new_association_ind;
|
||||
|
||||
|
||||
@@ -1116,7 +1116,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed)
|
||||
|
||||
/* We received a new connection request */
|
||||
if (sctp_create_new_listener(
|
||||
ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init,0) < 0) {
|
||||
/* SCTP socket creation or bind failed... */
|
||||
@@ -1131,7 +1131,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed)
|
||||
SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n");
|
||||
|
||||
multi_sd = sctp_create_new_listener(
|
||||
ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_multi,1);
|
||||
/* We received a new connection request */
|
||||
@@ -1141,27 +1141,27 @@ void *sctp_eNB_process_itti_msg(void *notUsed)
|
||||
}
|
||||
sctp_itti_send_init_msg_multi_cnf(
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
multi_sd);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_REQ: {
|
||||
sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
sctp_handle_new_association_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_req);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_REQ_MULTI: {
|
||||
sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
sctp_handle_new_association_req_multi(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_req_multi);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_CLOSE_ASSOCIATION:
|
||||
sctp_close_association(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
sctp_close_association(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_close_association);
|
||||
break;
|
||||
@@ -1172,7 +1172,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed)
|
||||
break;
|
||||
|
||||
case SCTP_DATA_REQ: {
|
||||
sctp_send_data(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
sctp_send_data(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
ITTI_MSG_ORIGIN_ID(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_req);
|
||||
}
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
//WARNING: sctp requires libsctp-dev and -lsctp as linker option
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "sctp_eNB_defs.h"
|
||||
#include "sctp_common.h"
|
||||
|
||||
#include "sctp_primitives_client.h"
|
||||
|
||||
#if defined(ENB_MODE)
|
||||
# include "eNB_default_values.h"
|
||||
#else
|
||||
# include "mme_default_values.h"
|
||||
#endif
|
||||
|
||||
/* Send buffer to SCTP association */
|
||||
int sctp_send_msg(sctp_data_t *sctp_data_p, uint16_t ppid, uint16_t stream,
|
||||
const uint8_t *buffer, const uint32_t length)
|
||||
{
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(sctp_data_p != NULL);
|
||||
|
||||
/* Send message on specified stream of the sd association
|
||||
* NOTE: PPID should be defined in network order
|
||||
*/
|
||||
if (sctp_sendmsg(sctp_data_p->sd, (const void *)buffer, length, NULL, 0,
|
||||
htonl(ppid), 0, stream, 0, 0) < 0) {
|
||||
SCTP_ERROR("Sctp_sendmsg failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
SCTP_DEBUG("Successfully sent %d bytes to port %d on stream %d\n",
|
||||
length, sctp_data_p->remote_port, stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int sctp_handle_notifications(union sctp_notification *snp)
|
||||
{
|
||||
if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) {
|
||||
/* Client deconnection */
|
||||
SCTP_DEBUG("Notification received: server deconnected\n");
|
||||
} else if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) {
|
||||
/* Association has changed */
|
||||
SCTP_DEBUG("Notification received: server association changed\n");
|
||||
} else {
|
||||
SCTP_DEBUG("Notification received: %d TODO\n", snp->sn_header.sn_type);
|
||||
}
|
||||
|
||||
/* TODO: handle more notif here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sctp_run(sctp_data_t *sctp_data_p)
|
||||
{
|
||||
int ret, repeat = 1;
|
||||
int total_size = 0;
|
||||
int sd;
|
||||
struct pollfd fds;
|
||||
|
||||
DevAssert(sctp_data_p != NULL);
|
||||
|
||||
sd = sctp_data_p->sd;
|
||||
|
||||
memset(&fds, 0, sizeof(struct pollfd));
|
||||
|
||||
fds.fd = sd;
|
||||
fds.events = POLLIN;
|
||||
|
||||
while (repeat == 1) {
|
||||
ret = poll(&fds, 1, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
SCTP_ERROR("[SD %d] Poll has failed (%d:%s)\n",
|
||||
sd, errno, strerror(errno));
|
||||
return errno;
|
||||
} else if (ret == 0) {
|
||||
/* No data to read, just leave the loop */
|
||||
SCTP_DEBUG("[SD %d] Poll: no data available\n", sd);
|
||||
repeat = 0;
|
||||
} else {
|
||||
/* Socket has some data to read */
|
||||
uint8_t buffer[SCTP_RECV_BUFFER_SIZE];
|
||||
int flags = 0;
|
||||
int n;
|
||||
struct sockaddr_in addr;
|
||||
struct sctp_sndrcvinfo sinfo;
|
||||
|
||||
socklen_t from_len;
|
||||
memset((void *)&addr, 0, sizeof(struct sockaddr_in));
|
||||
from_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||
memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
|
||||
|
||||
n = sctp_recvmsg(sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE,
|
||||
(struct sockaddr *)&addr, &from_len,
|
||||
&sinfo, &flags);
|
||||
|
||||
if (n < 0) {
|
||||
/* Other peer is deconnected */
|
||||
SCTP_ERROR("[SD %d] An error occured during read (%d:%s)\n",
|
||||
sd, errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & MSG_NOTIFICATION) {
|
||||
sctp_handle_notifications((union sctp_notification *)buffer);
|
||||
} else {
|
||||
struct sctp_queue_item_s *new_item_p;
|
||||
|
||||
new_item_p = calloc(1, sizeof(struct sctp_queue_item_s));
|
||||
/* Normal data received */
|
||||
SCTP_DEBUG("[SD %d] Msg of length %d received from %s:%u on "
|
||||
"stream %d, PPID %d, assoc_id %d\n",
|
||||
sd, n, inet_ntoa(addr.sin_addr),
|
||||
ntohs(addr.sin_port), sinfo.sinfo_stream,
|
||||
sinfo.sinfo_ppid, sinfo.sinfo_assoc_id);
|
||||
|
||||
new_item_p->local_stream = sinfo.sinfo_stream;
|
||||
new_item_p->remote_port = ntohs(addr.sin_port);
|
||||
new_item_p->remote_addr = addr.sin_addr.s_addr;
|
||||
new_item_p->ppid = sinfo.sinfo_ppid;
|
||||
new_item_p->assoc_id = sinfo.sinfo_assoc_id;
|
||||
new_item_p->length = n;
|
||||
new_item_p->buffer = malloc(sizeof(uint8_t) * n);
|
||||
|
||||
memcpy(new_item_p->buffer, buffer, n);
|
||||
|
||||
/* Insert the new packet at the tail of queue. */
|
||||
TAILQ_INSERT_TAIL(&sctp_data_p->sctp_queue, new_item_p, entry);
|
||||
|
||||
/* Update queue related data */
|
||||
sctp_data_p->queue_size += n;
|
||||
sctp_data_p->queue_length++;
|
||||
total_size += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total_size;
|
||||
}
|
||||
|
||||
int sctp_connect_to_remote_host(char *local_ip_addr[],
|
||||
int nb_local_addr,
|
||||
char *remote_ip_addr,
|
||||
uint16_t port,
|
||||
int socket_type,
|
||||
sctp_data_t *sctp_data_p)
|
||||
{
|
||||
int sd = -1;
|
||||
socklen_t i = 0;
|
||||
|
||||
struct sctp_initmsg init;
|
||||
struct sctp_event_subscribe events;
|
||||
struct sockaddr *bindx_add_addr;
|
||||
|
||||
DevAssert(sctp_data_p != NULL);
|
||||
DevAssert(remote_ip_addr != NULL);
|
||||
DevAssert(local_ip_addr != NULL);
|
||||
DevCheck((socket_type == SOCK_STREAM), socket_type, 0, 0);
|
||||
|
||||
SCTP_DEBUG("Creating socket type %d\n", socket_type);
|
||||
|
||||
/* Create new socket */
|
||||
if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
|
||||
SCTP_ERROR("Socket creation failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bind to provided IP adresses */
|
||||
bindx_add_addr = calloc(nb_local_addr, sizeof(struct sockaddr));
|
||||
|
||||
for (i = 0; i < nb_local_addr; i++) {
|
||||
if (inet_pton(AF_INET, local_ip_addr[i], &((struct sockaddr_in*)&bindx_add_addr[i])->sin_addr.s_addr) != 1) {
|
||||
if (inet_pton(AF_INET6, local_ip_addr[i], &((struct sockaddr_in6*)&bindx_add_addr[i])->sin6_addr.s6_addr) != 1) {
|
||||
continue;
|
||||
} else {
|
||||
((struct sockaddr_in6*)&bindx_add_addr[i])->sin6_port = 0;
|
||||
bindx_add_addr[i].sa_family = AF_INET6;
|
||||
}
|
||||
} else {
|
||||
((struct sockaddr_in*)&bindx_add_addr[i])->sin_port = 0;
|
||||
bindx_add_addr[i].sa_family = AF_INET;
|
||||
}
|
||||
}
|
||||
|
||||
if (sctp_bindx(sd, bindx_add_addr, nb_local_addr, SCTP_BINDX_ADD_ADDR) < 0) {
|
||||
SCTP_ERROR("Socket bind failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset((void *)&init, 0, sizeof(struct sctp_initmsg));
|
||||
|
||||
/* Request a number of in/out streams */
|
||||
init.sinit_num_ostreams = SCTP_OUT_STREAMS;
|
||||
init.sinit_max_instreams = SCTP_IN_STREAMS;
|
||||
init.sinit_max_attempts = SCTP_MAX_ATTEMPTS;
|
||||
|
||||
SCTP_DEBUG("Requesting (%d %d) (in out) streams\n", init.sinit_num_ostreams,
|
||||
init.sinit_max_instreams);
|
||||
|
||||
if (setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG,
|
||||
&init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) {
|
||||
SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Subscribe to all events */
|
||||
events.sctp_data_io_event = 1;
|
||||
events.sctp_association_event = 1;
|
||||
events.sctp_address_event = 1;
|
||||
events.sctp_send_failure_event = 1;
|
||||
events.sctp_peer_error_event = 1;
|
||||
events.sctp_shutdown_event = 1;
|
||||
events.sctp_partial_delivery_event = 1;
|
||||
|
||||
if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events,
|
||||
8) < 0) {
|
||||
SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* SOCK_STREAM socket type requires an explicit connect to the remote host
|
||||
* address and port.
|
||||
* Only use IPv4 for the first connection attempt
|
||||
*/
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
if (inet_pton(AF_INET, remote_ip_addr, &addr.sin_addr.s_addr) != 1) {
|
||||
SCTP_ERROR("Failed to convert ip address %s to network type\n", remote_ip_addr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
SCTP_DEBUG("[%d] Sending explicit connect to %s:%u\n", sd, remote_ip_addr,
|
||||
port);
|
||||
|
||||
/* Connect to remote host and port */
|
||||
if (sctp_connectx(sd, (struct sockaddr *)&addr, 1, NULL) < 0) {
|
||||
SCTP_ERROR("Connect to %s:%u failed: %s\n", remote_ip_addr,
|
||||
port, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get SCTP status */
|
||||
sctp_get_sockinfo(sd, &sctp_data_p->instreams, &sctp_data_p->outstreams,
|
||||
&sctp_data_p->assoc_id);
|
||||
|
||||
sctp_data_p->sd = sd;
|
||||
|
||||
sctp_get_peeraddresses(sd, &sctp_data_p->remote_ip_addresses, &sctp_data_p->nb_remote_addresses);
|
||||
sctp_get_localaddresses(sd, NULL, NULL);
|
||||
|
||||
TAILQ_INIT(&sctp_data_p->sctp_queue);
|
||||
|
||||
return sd;
|
||||
|
||||
err:
|
||||
|
||||
if (sd != 0) {
|
||||
close(sd);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sctp_eNB_defs.h"
|
||||
|
||||
#ifndef SCTP_PRIMITIVES_CLIENT_H_
|
||||
#define SCTP_PRIMITIVES_CLIENT_H_
|
||||
|
||||
/** @defgroup _sctp_impl_ SCTP Layer Reference Implementation
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief SCTP recv callback prototype. Will be called every time a message is
|
||||
* received on socket.
|
||||
* \param assocId SCTP association ID
|
||||
* \param stream SCTP stream on which data had been received
|
||||
* \param buffer Pointer to data (should be freed by user)
|
||||
* \param length Length of message received
|
||||
* @return Execution result
|
||||
*/
|
||||
typedef int (*sctp_recv_callback)(uint32_t assocId,
|
||||
uint32_t stream,
|
||||
uint8_t *buffer,
|
||||
uint32_t length);
|
||||
|
||||
/** \brief SCTP connected callback prototype. Will be called once the
|
||||
* association is ready.
|
||||
* \param args argument provided by upper layer
|
||||
* \param assocId SCTP association ID
|
||||
* \param instreams Number of input streams negotiated with remote peer
|
||||
* \param outstreams Number of output streams negotiated with remote peer
|
||||
* @return Execution result
|
||||
*/
|
||||
typedef int (*sctp_connected_callback)(void *args,
|
||||
uint32_t assocId,
|
||||
uint32_t instreams,
|
||||
uint32_t outstreams);
|
||||
|
||||
/** \brief Perform association to a remote peer
|
||||
* \param ip_addr Peer IPv4 address
|
||||
* \param port Remote port to connect to
|
||||
* \param args Upper layer args that will be provided to connected callback
|
||||
* \param connected_callback Connected callback
|
||||
* \param recv_callback Data received callback
|
||||
* @return < 0 in case of failure
|
||||
*/
|
||||
int sctp_connect_to_remote_host(char *local_ip_addr[],
|
||||
int nb_local_addr,
|
||||
char *remote_ip_addr,
|
||||
uint16_t port,
|
||||
int socket_type,
|
||||
sctp_data_t *sctp_data_p);
|
||||
|
||||
/** \brief Send message over SCTP
|
||||
* \param sctp_data_p Pointer to the SCTP desc
|
||||
* \param ppid Payload Protocol Identifier
|
||||
* \param stream SCTP stream on which data will be sent
|
||||
* \param buffer Pointer to buffer
|
||||
* \param length Buffer length
|
||||
* @return < 0 in case of failure
|
||||
*/
|
||||
int sctp_send_msg(sctp_data_t *sctp_data_p, uint16_t ppid, uint16_t stream,
|
||||
const uint8_t *buffer, const uint32_t length);
|
||||
|
||||
/** \brief Flush the FIFO of messages from the socket
|
||||
* \param sctp_data_p
|
||||
* @return < 0 in case of failure
|
||||
*/
|
||||
int sctp_run(sctp_data_t *sctp_data_p);
|
||||
|
||||
/** \brief Properly disconnect the peer
|
||||
* \param assoc_id The SCTP association ID
|
||||
* @return < 0 in case of failure
|
||||
*/
|
||||
void sctp_disconnect(uint32_t assoc_id);
|
||||
|
||||
void sctp_terminate(void);
|
||||
|
||||
/* @} */
|
||||
#endif /* SCTP_PRIMITIVES_CLIENT_H_ */
|
||||
Reference in New Issue
Block a user