/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdlib.h>
#include <string.h>
#include "Sctp.h"
#include "jni.h"
#include "nio_util.h"
#include "nio.h"
#include "net_util.h"
#include "net_util_md.h"
#include "sun_nio_ch_SctpNet.h"
#include "sun_nio_ch_SctpChannelImpl.h"
#include "sun_nio_ch_SctpAssocChange.h"
#include "sun_nio_ch_SctpResultContainer.h"
#include "sun_nio_ch_SctpPeerAddrChange.h"
/* sizeof(union sctp_notification */
struct controlData {
int assocId;
unsigned short streamNumber;
unsigned int ppid;
};
/* defined in SctpNet.c */
/* use SocketChannelImpl's checkConnect implementation */
/*
* Class: sun_nio_ch_SctpChannelImpl
* Method: initIDs
* Signature: ()V
*/
/* SctpMessageInfoImpl */
"(ILjava/net/SocketAddress;IIZZI)V");
/* SctpResultContainer */
/* SctpSendFailed */
"(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
/* SctpAssocChange */
/* SctpPeerAddrChange */
"(ILjava/net/SocketAddress;I)V");
/* sun.nio.ch.SctpShutdown */
}
void getControlData
return;
}
}
return;
}
void setControlData
/* Initialize the payload */
if (cdata->streamNumber > 0) {
}
}
}
}
/* Sum of the length of all control messages in the buffer. */
}
// TODO: test: can create send failed without any data? if so need to
// update API so that buffer can be null if no data.
void handleSendFailed
char *addressP;
/* the actual undelivered message data is directly after the ssf */
/* the number of bytes remaining to be read in the sctp_send_failed notif*/
/* the size of the actual undelivered message */
/* retrieved address from sockaddr */
/* data retrieved from sff_data */
if (dataLength > 0) {
dataP += dataOffset;
return;
}
if (alreadyRead > 0) {
} else {
}
if (remaining > 0) {
return;
}
//TODO: assert false: "should not reach here";
return;
}
// TODO: Set and document (in API) buffers position.
}
}
/* create SctpSendFailed */
}
void handleAssocChange
int state = 0;
case SCTP_COMM_UP :
break;
case SCTP_COMM_LOST :
break;
case SCTP_RESTART :
break;
case SCTP_SHUTDOWN_COMP :
break;
case SCTP_CANT_STR_ASSOC :
}
/* create SctpAssociationChanged */
}
void handleShutdown
/* create SctpShutdown */
}
void handlePeerAddrChange
int event = 0;
switch (state) {
case SCTP_ADDR_AVAILABLE :
break;
case SCTP_ADDR_UNREACHABLE :
break;
case SCTP_ADDR_REMOVED :
break;
case SCTP_ADDR_ADDED :
break;
case SCTP_ADDR_MADE_PRIM :
#ifndef __solaris__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
break;
case SCTP_ADDR_CONFIRMED :
#endif /* __solaris__ */
}
/* create SctpPeerAddressChanged */
addressObj, event);
}
void handleUninteresting
(union sctp_notification *snp) {
//fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
}
/**
* Handle notifications from the SCTP stack.
* Returns JNI_TRUE if the notification is one that is of interest to the
* Java API, otherwise JNI_FALSE.
*/
case SCTP_SEND_FAILED:
return JNI_TRUE;
case SCTP_ASSOC_CHANGE:
return JNI_TRUE;
case SCTP_SHUTDOWN_EVENT:
return JNI_TRUE;
case SCTP_PEER_ADDR_CHANGE:
return JNI_TRUE;
default :
/* the Java API is not interested in this event, maybe we are? */
}
return JNI_FALSE;
}
void handleMessage
if (read == 0) {
/* we reached EOF */
read = -1;
}
/* create SctpMessageInfoImpl */
}
/*
* Class: sun_nio_ch_SctpChannelImpl
* Method: receive0
* Signature: (ILsun/nio/ch/SctpResultContainer;JIZ)I
*/
/* Set up the msghdr structure for receiving */
do {
if (errno == EWOULDBLOCK) {
return IOS_UNAVAILABLE;
return IOS_INTERRUPTED;
#ifdef __linux__
/* ENOTCONN when EOF reached */
rv = 0;
/* there will be no control data */
msg->msg_controllen = 0;
#endif /* __linux__ */
} else {
return 0;
}
}
return 0;
}
}
/* We have received a notification that is of interest to
to the Java API. The appropriate notification will be
set in the result container. */
return 0;
}
// set iov back to addr, and reset msg_controllen
}
return rv;
}
/*
* Class: sun_nio_ch_SctpChannelImpl
* Method: send0
* Signature: (IJILjava/net/InetAddress;IIIZI)I
*/
/* SctpChannel:
* targetAddress may contain the preferred address or NULL to use primary,
* assocId will always be -1
* SctpMultiChannell:
* Setup new association, targetAddress will contain address, assocId = -1
* Association already existing, assocId != -1, targetAddress = preferred addr
*/
return IOS_THROWN;
}
} else {
sa_len = 0;
}
/* Set up the msghdr structure for sending */
if (errno == EWOULDBLOCK) {
return IOS_UNAVAILABLE;
return IOS_INTERRUPTED;
"Socket is shutdown for writing");
} else {
return 0;
}
}
return rv;
}
/*
* Class: sun_nio_ch_SctpChannelImpl
* Method: checkConnect
* Signature: (Ljava/io/FileDescriptor;ZZ)I
*/
}