167 lines
6.8 KiB
C
167 lines
6.8 KiB
C
|
|
#ifndef _NORM_SOCKET
|
|
#define _NORM_SOCKET
|
|
|
|
// IMPORTANT NOTE: THIS IS A WORK IN PROGRESS. This code, if/when fully developed, will be
|
|
// "promoted" from the 'examples' directory to a standard part of the NORM
|
|
// library if appropriate.
|
|
|
|
// This provides a higher level API that facilitates a socket-like programming interface
|
|
// to use NORM for a specific usage pattern. The usage pattern uses NORM_OBJECT_STREAM
|
|
// (as a byte-stream initially with eventual support for NORM's message-stream capability, too)
|
|
// where "clients" explicitly connect to a "server" and bi-directional stream communication is
|
|
// established. This enables ACK-based flow control to/from the server and client(s). This
|
|
// is supported for NORM unicast and also (as this is completed) an asymmetric model where the
|
|
// server can multicast to the clients while the clients unicast back to the server.
|
|
|
|
|
|
// TODO:
|
|
//
|
|
// 0) Make "NormInstanceHandle" optional for Listen/Connect/Accept
|
|
// (for eventual blocking usage, it wouldn't be needed)
|
|
// 1) Support asymmetric server->multicast, client->unicast model (DONE)
|
|
// 2) Provide non-blocking option for read/write calls
|
|
// 3) leverage ICMP (e.g., port unreachable) feedback to detect connect() failure (DONE)
|
|
// 4) provide means for connect() to time out??? (DONE)
|
|
// 5) Separate socket open (i.e. session creation) from connect/accept to allow
|
|
// opportunity for application to set NORM parameters prior to sender/receiver start
|
|
// 6) Extend to include message stream, and data/file object sockets
|
|
// 7) Option to associate NORM_INFO w/ stream (or objects eventually)
|
|
|
|
|
|
// Here is a list of NORM parameters that need to be set _before_ sender or receiver
|
|
// startup. These will need to be "NormSocket" parameters that can be set after
|
|
// NormOpen() but before NormListen(), NormAccept(), or NormConnect():
|
|
//
|
|
// a) SSM source address (perhaps incorporate into NormListen() and NormConnect()?)
|
|
// b) TTL (could be set _after_ connect/accept, but may be something convenient to preset?
|
|
// c) TOS (same as for TTL)
|
|
// d) Fragmentation (not one to worry much about initially?)
|
|
// e) FEC parameters (block size, parity count, segment size, "auto" parity)
|
|
// f) Buffer size (sender, stream, receiver)
|
|
// g) cache bounds / limits
|
|
|
|
|
|
#ifdef WIN32
|
|
#include <BaseTsd.h> // for SSIZE_T
|
|
typedef SSIZE_T ssize_t;
|
|
#endif // WIN32
|
|
|
|
#include "normApi.h"
|
|
|
|
typedef const void* NormSocketHandle;
|
|
|
|
extern const NormSocketHandle NORM_SOCKET_INVALID;
|
|
|
|
extern const double NORM_DEFAULT_CONNECT_TIMEOUT;
|
|
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif // !NULL
|
|
|
|
// Main NormSocket API Functions
|
|
|
|
NormSocketHandle NormOpen(NormInstanceHandle instance);
|
|
|
|
bool NormListen(NormSocketHandle normSocket,
|
|
UINT16 serverPort,
|
|
const char* groupAddr = NULL,
|
|
const char* serverAddr = NULL);
|
|
|
|
bool NormConnect(NormSocketHandle normSocket,
|
|
const char* serverAddr,
|
|
UINT16 serverPort,
|
|
UINT16 localPort = 0,
|
|
const char* groupAddr = NULL,
|
|
NormNodeId clientId = NORM_NODE_ANY);
|
|
|
|
NormSocketHandle NormAccept(NormSocketHandle serverSocket,
|
|
NormNodeHandle clientNode,
|
|
NormInstanceHandle instance = NORM_INSTANCE_INVALID);
|
|
|
|
void NormReject(NormSocketHandle serverSocket,
|
|
NormNodeHandle clientNode);
|
|
|
|
void NormShutdown(NormSocketHandle normSocket);
|
|
|
|
void NormClose(NormSocketHandle normSocket);
|
|
|
|
ssize_t NormRead(NormSocketHandle normSocket, void* buf, size_t nbyte);
|
|
|
|
ssize_t NormWrite(NormSocketHandle normSocket, const void* buf, size_t nbyte);
|
|
|
|
int NormFlush(NormSocketHandle normSocket);
|
|
|
|
// NormSocket helper functions
|
|
|
|
void NormSetSocketUserData(NormSocketHandle normSocket, const void* userData);
|
|
const void* NormGetSocketUserData(NormSocketHandle normSocket);
|
|
|
|
NormInstanceHandle NormGetSocketInstance(NormSocketHandle normSocket);
|
|
NormSessionHandle NormGetSocketSession(NormSocketHandle normSocket);
|
|
NormSessionHandle NormGetSocketMulticastSession(NormSocketHandle normSocket);
|
|
void NormGetPeerName(NormSocketHandle normSocket, char* addr, unsigned int* addrLen, UINT16* port);
|
|
NormObjectHandle NormGetSocketTxStream(NormSocketHandle normSocket);
|
|
NormObjectHandle NormGetSocketRxStream(NormSocketHandle normSocket);
|
|
|
|
void NormSetSocketFlowControl(NormSocketHandle normSocket, bool enable);
|
|
void NormSetSocketTrace(NormSocketHandle normSocket, bool enable);
|
|
|
|
typedef enum NormSocketEventType
|
|
{
|
|
NORM_SOCKET_NONE = 0, // applications should generally ignore these
|
|
NORM_SOCKET_ACCEPT, // only issued for listening server sockets
|
|
NORM_SOCKET_CONNECT, // notification confirming connection to server
|
|
NORM_SOCKET_READ, // edge-triggered notification that socket is ready for reading
|
|
NORM_SOCKET_WRITE, // edge-triggered notification that socket is ready for writing
|
|
NORM_SOCKET_CLOSING, // indicates remote endpoint is closing socket (only read data at this point)
|
|
NORM_SOCKET_CLOSE // indicates socket is now closed (invalid for further operations)
|
|
} NormSocketEventType;
|
|
|
|
|
|
// Right now, these options MUST be set _after_ NormOpen()
|
|
// but _before_ NormConnect() or NormListen()
|
|
// (This will be expanded, perhaps to include parameters
|
|
// that can be changed after connection setup)
|
|
typedef struct
|
|
{
|
|
UINT16 num_data;
|
|
UINT16 num_parity;
|
|
UINT16 num_auto;
|
|
UINT16 segment_size;
|
|
unsigned int buffer_size; // used for both FEC and stream buffer sizing
|
|
bool silent_receiver; // not yet used (maybe should be nack_mode instead)
|
|
int max_delay; // not yet used
|
|
} NormSocketOptions;
|
|
|
|
void NormGetSocketOptions(NormSocketHandle normSocket, NormSocketOptions* options);
|
|
bool NormSetSocketOptions(NormSocketHandle normSocket, NormSocketOptions* options);
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
typedef struct
|
|
{
|
|
NormSocketEventType type;
|
|
NormSocketHandle socket;
|
|
// The underlying NormEvent is embedded. The union
|
|
// here lets us access the NormEvent fields directly.
|
|
// (E.g., *.sender, *.object, etc. as needed)
|
|
union
|
|
{
|
|
NormEvent event; // underlying NormEvent that evoked this socketEvent
|
|
struct
|
|
{
|
|
NormEventType etype; // underlying NormEventType
|
|
NormSessionHandle session; // NormEvent session
|
|
NormNodeHandle sender; // NormEvent sender
|
|
NormObjectHandle object; // NormEvent object
|
|
};
|
|
};
|
|
} NormSocketEvent;
|
|
#pragma GCC diagnostic pop
|
|
|
|
bool NormGetSocketEvent(NormInstanceHandle normInstance, NormSocketEvent* event, bool waitForEvent = true);
|
|
|
|
|
|
#endif // !_NORM_SOCKET
|