v1.5r5
parent
5be33c4e24
commit
76edf0c18d
17
VERSION.TXT
17
VERSION.TXT
|
|
@ -1,5 +1,20 @@
|
||||||
NORM Version History
|
NORM Version History
|
||||||
|
|
||||||
|
Version 1.5r5
|
||||||
|
=============
|
||||||
|
- Added NORM_REMOTE_SENDER_RESET event to notify app when the sender
|
||||||
|
has been reset due to instance id, etc change
|
||||||
|
- Fixed possibly critical issue in Protolib ProtoDispatcher where
|
||||||
|
threaded dispatcher use (as the NORM API uses) could possibly result
|
||||||
|
in timers not being serviced properly. Most likely the issue could
|
||||||
|
only occur under certain, heavier NORM API usage patterns. Nonetheless,
|
||||||
|
this is an important fix. (Thanks to Michael Savisko of Arris).
|
||||||
|
- Fixed FreeBSD build (Thanks to Hans Duedal)
|
||||||
|
- Changed from 'b' (build) numbering schema to 'r' (release) to reduce
|
||||||
|
confusion with respect to "beta" versus "stable" releases.
|
||||||
|
- Note there are some "in-progress" API extensions in this release that
|
||||||
|
are not yet described in the developer's guide documentation.
|
||||||
|
|
||||||
Version 1.5b4
|
Version 1.5b4
|
||||||
=============
|
=============
|
||||||
- Corrected change in behavior of non-blocking version of
|
- Corrected change in behavior of non-blocking version of
|
||||||
|
|
@ -24,7 +39,7 @@ Version 1.5b2
|
||||||
notification check acking status). Acknowledged, graceful shutdown streams,
|
notification check acking status). Acknowledged, graceful shutdown streams,
|
||||||
are automatically closed.
|
are automatically closed.
|
||||||
- Fixed issue with compilation for NormObjectSize constructor, MSB(), and LSB()
|
- Fixed issue with compilation for NormObjectSize constructor, MSB(), and LSB()
|
||||||
methods on 32-bit systems. Thanks to Bill Skiba.
|
methods on 32-bit systems. (Thanks to Bill Skiba).
|
||||||
|
|
||||||
Version 1.5b1
|
Version 1.5b1
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -5,9 +5,9 @@
|
||||||
<articleinfo>
|
<articleinfo>
|
||||||
<title><inlinemediaobject>
|
<title><inlinemediaobject>
|
||||||
<imageobject>
|
<imageobject>
|
||||||
<imagedata align="center" fileref="NormLogo.gif" scale="50" />
|
<imagedata align="center" fileref="NormLogo.gif" scale="50"/>
|
||||||
</imageobject>
|
</imageobject>
|
||||||
</inlinemediaobject> NORM Developer's Guide (version 1.4b4)</title>
|
</inlinemediaobject> NORM Developer's Guide (version 1.5b5)</title>
|
||||||
|
|
||||||
<titleabbrev>NORM Developer's Guide</titleabbrev>
|
<titleabbrev>NORM Developer's Guide</titleabbrev>
|
||||||
|
|
||||||
|
|
@ -1234,9 +1234,9 @@ bool <link linkend="NormGetNextEvent"><literal>NormGetNextEvent</literal></link>
|
||||||
|
|
||||||
<informaltable frame="all">
|
<informaltable frame="all">
|
||||||
<tgroup cols="2">
|
<tgroup cols="2">
|
||||||
<colspec colnum="1" colwidth="1*" />
|
<colspec colnum="1" colwidth="1*"/>
|
||||||
|
|
||||||
<colspec colnum="2" colwidth="2.5*" />
|
<colspec colnum="2" colwidth="2.5*"/>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
|
|
@ -1430,8 +1430,8 @@ bool <link linkend="NormGetNextEvent"><literal>NormGetNextEvent</literal></link>
|
||||||
<entry><para><literal>NORM_REMOTE_SENDER_ACTIVE</literal></para></entry>
|
<entry><para><literal>NORM_REMOTE_SENDER_ACTIVE</literal></para></entry>
|
||||||
|
|
||||||
<entry><para>This event is posted when a previously inactive
|
<entry><para>This event is posted when a previously inactive
|
||||||
(or new) remote <anchor id="OLE_LINK5" /> <anchor
|
(or new) remote <anchor id="OLE_LINK5"/> <anchor
|
||||||
id="OLE_LINK4" />sender is detected operating as an active
|
id="OLE_LINK4"/>sender is detected operating as an active
|
||||||
sender within the session.</para></entry>
|
sender within the session.</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
|
@ -1675,9 +1675,9 @@ NormSessionHandle</literal></link> <link linkend="NormCreateSession"><literal>No
|
||||||
|
|
||||||
<informaltable frame="all">
|
<informaltable frame="all">
|
||||||
<tgroup cols="2">
|
<tgroup cols="2">
|
||||||
<colspec colnum="1" colwidth="1*" />
|
<colspec colnum="1" colwidth="1*"/>
|
||||||
|
|
||||||
<colspec colnum="2" colwidth="5*" />
|
<colspec colnum="2" colwidth="5*"/>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
|
|
@ -1886,7 +1886,7 @@ const void* <link linkend="NormGetUserData"><literal>NormGetUserData</literal></
|
||||||
</sect4>
|
</sect4>
|
||||||
|
|
||||||
<sect4>
|
<sect4>
|
||||||
<title>Return Values</title>
|
<title>Return Valuess</title>
|
||||||
|
|
||||||
<para>The returned value indicates the <emphasis>NormNode</emphasis>
|
<para>The returned value indicates the <emphasis>NormNode</emphasis>
|
||||||
identifier used by the NORM protocol engine for the local
|
identifier used by the NORM protocol engine for the local
|
||||||
|
|
@ -2185,8 +2185,8 @@ NormSetMulticastInterface</literal></link>(session, "interface2");</programlisti
|
||||||
|
|
||||||
<para>A return value of <constant>true</constant> indicates success
|
<para>A return value of <constant>true</constant> indicates success
|
||||||
while a return value of <constant>false</constant> indicates that
|
while a return value of <constant>false</constant> indicates that
|
||||||
the specified interface was valid. This function will always return
|
the specified interface was invalid. This function will always
|
||||||
<constant>true</constant> if made before calls to <link
|
return <constant>true</constant> if made before calls to <link
|
||||||
linkend="NormStartSender"><literal>NormStartSender()</literal></link>
|
linkend="NormStartSender"><literal>NormStartSender()</literal></link>
|
||||||
or <link
|
or <link
|
||||||
linkend="NormStartReceiver"><literal>NormStartReceiver()</literal></link>.
|
linkend="NormStartReceiver"><literal>NormStartReceiver()</literal></link>.
|
||||||
|
|
@ -2195,6 +2195,50 @@ NormSetMulticastInterface</literal></link>(session, "interface2");</programlisti
|
||||||
</sect4>
|
</sect4>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
|
<sect3 id="NormSetMulticastInterface">
|
||||||
|
<title>NormSetSSM()</title>
|
||||||
|
|
||||||
|
<sect4>
|
||||||
|
<title>Synopsis</title>
|
||||||
|
|
||||||
|
<programlisting>#include <normApi.h>
|
||||||
|
|
||||||
|
bool <link linkend="NormSetMulticastInterface"><literal>NormSetSSM</literal></link>(<link
|
||||||
|
linkend="NormSessionHandle"><literal>NormSessionHandle</literal></link> session,
|
||||||
|
const char* sourceAddress);</programlisting>
|
||||||
|
</sect4>
|
||||||
|
|
||||||
|
<sect4>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>This function sets the source address for Source-Specific
|
||||||
|
Multicast (SSM) operation. This should be called
|
||||||
|
<emphasis>before</emphasis> any call to <link
|
||||||
|
linkend="NormStartSender"><literal>NormStartSender()</literal></link>
|
||||||
|
or <link
|
||||||
|
linkend="NormStartReceiver"><literal>NormStartReceiver()</literal></link>
|
||||||
|
is made so that the proper group join is done. The receiver
|
||||||
|
application MUST also use the <link
|
||||||
|
linkend="NormSetDefaultUnicastNack"><literal>NormSetDefaultUnicastNack()</literal></link>
|
||||||
|
call so that feedback traffic is directed back to appropriate
|
||||||
|
sender.</para>
|
||||||
|
</sect4>
|
||||||
|
|
||||||
|
<sect4>
|
||||||
|
<title>Return Values</title>
|
||||||
|
|
||||||
|
<para>A return value of <constant>true</constant> indicates success
|
||||||
|
while a return value of <constant>false</constant> indicates that
|
||||||
|
the specified source address was invalid. Note that if a valid IP
|
||||||
|
address is specified but is improper for SSM (e.g., an IP multicast
|
||||||
|
address) the later calls to <link
|
||||||
|
linkend="NormStartSender"><literal>NormStartSender()</literal></link>
|
||||||
|
or <link
|
||||||
|
linkend="NormStartReceiver"><literal>NormStartReceiver()</literal></link>
|
||||||
|
may fail.</para>
|
||||||
|
</sect4>
|
||||||
|
</sect3>
|
||||||
|
|
||||||
<sect3 id="NormSetTTL">
|
<sect3 id="NormSetTTL">
|
||||||
<title>NormSetTTL()</title>
|
<title>NormSetTTL()</title>
|
||||||
|
|
||||||
|
|
@ -2352,8 +2396,7 @@ bool <link linkend="NormSetFragmentation"><literal>NormSetFragmentation</literal
|
||||||
Multicast destinations, some operating systems may always set the DF
|
Multicast destinations, some operating systems may always set the DF
|
||||||
bit of transmitted packets, regardless of the setting here and the
|
bit of transmitted packets, regardless of the setting here and the
|
||||||
underlying socket option status. Typically, the DF bit is set (i.e.,
|
underlying socket option status. Typically, the DF bit is set (i.e.,
|
||||||
fragmentation disabled) by default on most operating systems.
|
fragmentation disabled) by default on most operating systems.</para>
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>This call is not currently functional on the Mac OSX system
|
<para>This call is not currently functional on the Mac OSX system
|
||||||
that does not support the needed
|
that does not support the needed
|
||||||
|
|
@ -2371,7 +2414,7 @@ bool <link linkend="NormSetFragmentation"><literal>NormSetFragmentation</literal
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2>
|
<sect2>
|
||||||
<title><anchor id="_NORM_Sender_Functions" />NORM Sender
|
<title><anchor id="_NORM_Sender_Functions"/>NORM Sender
|
||||||
Functions</title>
|
Functions</title>
|
||||||
|
|
||||||
<para>The functions described in this section apply only to NORM sender
|
<para>The functions described in this section apply only to NORM sender
|
||||||
|
|
@ -2412,9 +2455,9 @@ bool <link linkend="NormStartSender"><literal>NormStartSender</literal></link>(<
|
||||||
|
|
||||||
<informaltable frame="all">
|
<informaltable frame="all">
|
||||||
<tgroup cols="2">
|
<tgroup cols="2">
|
||||||
<colspec colnum="1" colwidth="1*" />
|
<colspec colnum="1" colwidth="1*"/>
|
||||||
|
|
||||||
<colspec colnum="2" colwidth="5*" />
|
<colspec colnum="2" colwidth="5*"/>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,296 @@
|
||||||
|
#include "normSocket.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <fcntl.h> // for, well, fnctl()
|
||||||
|
#include <errno.h> // obvious child
|
||||||
|
|
||||||
|
// BUILD: (assumes "normApi.h" in "include" ...
|
||||||
|
// g++ -I../include -o normClient normClient.cpp normSocket.cpp ../lib/libnorm.a ../protolib/lib/libprotokit.a -lresolv
|
||||||
|
|
||||||
|
|
||||||
|
// NOTES:
|
||||||
|
// 1) THIS IS A WORK IN PROGRESS AND NOT YET FUNCTIONAL!
|
||||||
|
// 2) Some of the functions here may be added to the NORM API in the future.
|
||||||
|
|
||||||
|
// Client initiates connection to "server". When the "client" gets a NORM_REMOTE_SENDER_NEW
|
||||||
|
// from the "server", it knows its connection has been accepted.
|
||||||
|
|
||||||
|
// To deny a connection, the "server" can send a stream close??? Which means the server will have
|
||||||
|
// to establish state just to deny a client a connection (yuck!)
|
||||||
|
|
||||||
|
const unsigned int MSG_LENGTH_MAX = 64;
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
char serverAddr[64];
|
||||||
|
strcpy(serverAddr, "127.0.0.1");
|
||||||
|
UINT16 serverPort = 5000;
|
||||||
|
char groupAddr[64];
|
||||||
|
const char* groupAddrPtr = NULL;
|
||||||
|
const char* mcastInterface = NULL;
|
||||||
|
NormNodeId clientId = 2;
|
||||||
|
bool trace = false;
|
||||||
|
unsigned int debugLevel = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
const char* cmd = argv[i];
|
||||||
|
unsigned int len = strlen(cmd);
|
||||||
|
if (0 == strncmp(cmd, "connect", len))
|
||||||
|
{
|
||||||
|
// connect <serverAddr>/<port>[,<groupAddr>
|
||||||
|
const char* val = argv[++i];
|
||||||
|
const char* portPtr = strchr(val, '/');
|
||||||
|
if (NULL == portPtr)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient error: missing <port> number\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
portPtr++;
|
||||||
|
unsigned int addrTextLen = portPtr - val;
|
||||||
|
if (addrTextLen > 0)
|
||||||
|
{
|
||||||
|
addrTextLen -= 1;
|
||||||
|
strncpy(serverAddr, val, addrTextLen);
|
||||||
|
serverAddr[addrTextLen] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient error: missing <serverAddr>\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char portText[32];
|
||||||
|
const char* groupPtr = strchr(portPtr, ',');
|
||||||
|
if (NULL == groupPtr)
|
||||||
|
{
|
||||||
|
strcpy(portText, portPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
groupPtr++;
|
||||||
|
unsigned int portTextLen = groupPtr - portPtr - 1;
|
||||||
|
strncpy(portText, portPtr, portTextLen);
|
||||||
|
portText[portTextLen] = '\0';
|
||||||
|
}
|
||||||
|
if (1 != sscanf(portText, "%hu", &serverPort))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient error: invalid <port>\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (NULL != groupPtr)
|
||||||
|
{
|
||||||
|
strcpy(groupAddr, groupPtr);
|
||||||
|
groupAddrPtr = groupAddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "interface", len))
|
||||||
|
{
|
||||||
|
mcastInterface = argv[++i];
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "trace", len))
|
||||||
|
{
|
||||||
|
trace = true;
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "debug", len))
|
||||||
|
{
|
||||||
|
if (1 != sscanf(argv[++i], "%u", &debugLevel))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer error: invalid debug level\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "id", len))
|
||||||
|
{
|
||||||
|
const char* val = argv[++i];
|
||||||
|
unsigned long id;
|
||||||
|
if (1 != sscanf(val, "%lu", &id))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient error: invalid 'id' value\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
clientId = id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer error: invalid command \"%s\"\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NormInstanceHandle instance = NormCreateInstance();
|
||||||
|
|
||||||
|
// Initate connection to server ...
|
||||||
|
fprintf(stderr, "normClient: connecting to %s/%hu ...\n", serverAddr, serverPort);
|
||||||
|
NormSocketHandle normSocket = NormConnect(instance, serverAddr, serverPort, groupAddrPtr, clientId);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
{
|
||||||
|
NormSetMessageTrace(NormGetSession(normSocket), true);
|
||||||
|
if (NULL != groupAddrPtr)
|
||||||
|
NormSetMessageTrace(NormGetMulticastSession(normSocket), true);
|
||||||
|
}
|
||||||
|
if (0 != debugLevel) NormSetDebugLevel(debugLevel);
|
||||||
|
|
||||||
|
//NormSetDebugLevel(3);
|
||||||
|
//NormSetMessageTrace(NormGetSession(normSocket), true);
|
||||||
|
|
||||||
|
// We use a select() call to multiplex input reading and NormSocket handling
|
||||||
|
fd_set fdset;
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
|
||||||
|
// Get our input (STDIN) descriptor and set non-blocking
|
||||||
|
FILE* inputFile = stdin;
|
||||||
|
int inputfd = fileno(inputFile);
|
||||||
|
if (-1 == fcntl(inputfd, F_SETFL, fcntl(inputfd, F_GETFL, 0) | O_NONBLOCK))
|
||||||
|
perror("normClient: fcntl(inputfd, O_NONBLOCK) error");
|
||||||
|
// Get our NormInstance descriptor
|
||||||
|
int normfd = NormGetDescriptor(instance);
|
||||||
|
bool keepGoing = true;
|
||||||
|
bool writeReady = false;
|
||||||
|
unsigned int inputLength = 0;
|
||||||
|
unsigned int bytesWritten = 0;
|
||||||
|
const unsigned int BUFFER_LENGTH = 2048;
|
||||||
|
char inputBuffer[BUFFER_LENGTH];
|
||||||
|
bool inputNeeded = false; // will be set to "true" upon CONNECT
|
||||||
|
while (keepGoing)
|
||||||
|
{
|
||||||
|
FD_SET(normfd, &fdset);
|
||||||
|
int maxfd = normfd;
|
||||||
|
if (inputNeeded)
|
||||||
|
{
|
||||||
|
FD_SET(inputfd, &fdset);
|
||||||
|
if (inputfd > maxfd) maxfd = inputfd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FD_CLR(inputfd, &fdset);
|
||||||
|
}
|
||||||
|
int result = select(maxfd+1, &fdset, NULL, NULL, NULL);
|
||||||
|
if (result <= 0)
|
||||||
|
{
|
||||||
|
perror("normClient: select() error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(inputfd, &fdset))
|
||||||
|
{
|
||||||
|
// Read input into our txBuffer
|
||||||
|
inputLength = fread(inputBuffer, 1, BUFFER_LENGTH, inputFile);
|
||||||
|
if (inputLength > 0)
|
||||||
|
{
|
||||||
|
// We got our input
|
||||||
|
bytesWritten = 0;
|
||||||
|
inputNeeded = false;
|
||||||
|
}
|
||||||
|
else if (feof(inputFile))
|
||||||
|
{
|
||||||
|
// TBD - initiate client shutdown
|
||||||
|
if (NULL == groupAddrPtr)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient: CLOSING connection to server ...\n");
|
||||||
|
NormShutdown(normSocket);
|
||||||
|
}
|
||||||
|
inputNeeded = false; // TBD -should we also fclose(inputFile)???
|
||||||
|
|
||||||
|
// else stick around to receive stuff from the server
|
||||||
|
}
|
||||||
|
else if (ferror(inputFile))
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EINTR:
|
||||||
|
// interupted, try again
|
||||||
|
break;
|
||||||
|
case EAGAIN:
|
||||||
|
// input starved, wait for next notification
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
perror("normClient: error reading input");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FD_ISSET(normfd, &fdset))
|
||||||
|
{
|
||||||
|
|
||||||
|
// There's a NORM event pending
|
||||||
|
NormSocketEvent event;
|
||||||
|
if (NormGetSocketEvent(instance, &event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case NORM_SOCKET_ACCEPT:
|
||||||
|
// shouldn't happen
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORM_SOCKET_CONNECT:
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient: CONNECTED to server ...\n");
|
||||||
|
inputNeeded = true;
|
||||||
|
writeReady = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_READ:
|
||||||
|
{
|
||||||
|
// This is a cue to try to read data from stream
|
||||||
|
// For our test app here, the data is read and output to STDOUT
|
||||||
|
bool rxReady = true;
|
||||||
|
while (rxReady)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
ssize_t bytesRead = NormRead(event.socket, buffer, 1024);
|
||||||
|
if (bytesRead < 0)
|
||||||
|
{
|
||||||
|
// This shouldn't happen with ack-based flow control used
|
||||||
|
fprintf(stderr, "normClient: broken stream ...\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bytesRead > 0)
|
||||||
|
fwrite(buffer, sizeof(char), bytesRead, stdout);
|
||||||
|
if (bytesRead < 1024) rxReady = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_WRITE:
|
||||||
|
writeReady = true;
|
||||||
|
break;
|
||||||
|
case NORM_SOCKET_CLOSING:
|
||||||
|
fprintf(stderr, "normClient: server CLOSING connection ...\n");
|
||||||
|
inputNeeded = false;
|
||||||
|
break;
|
||||||
|
case NORM_SOCKET_CLOSED:
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient: connection to server CLOSED.\n");
|
||||||
|
inputNeeded = false;
|
||||||
|
keepGoing = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_NONE:
|
||||||
|
break;
|
||||||
|
} // end switch(event.type)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normClient: NormGetSocketEvent() returned false\n");
|
||||||
|
}
|
||||||
|
} // end if FD_ISSET(normfd)
|
||||||
|
|
||||||
|
// If we have data in our inputBuffer and the NormSocket is "writeReady", then send it
|
||||||
|
if (writeReady && (inputLength > 0))
|
||||||
|
{
|
||||||
|
bytesWritten += NormWrite(normSocket, inputBuffer + bytesWritten, inputLength - bytesWritten);
|
||||||
|
if (bytesWritten < inputLength)
|
||||||
|
{
|
||||||
|
// Couldn't write whole inputBuffer, need to wait for NORM_SOCKET_WRITE event
|
||||||
|
writeReady = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// inputBuffer has been completely written
|
||||||
|
inputLength = 0;
|
||||||
|
inputNeeded = true;
|
||||||
|
NormFlush(normSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end while(keepGoing)
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "normApi.h"
|
#include "normApi.h"
|
||||||
|
|
||||||
|
#include "protoCheck.h"
|
||||||
|
|
||||||
#include <stdio.h> // for printf(), etc
|
#include <stdio.h> // for printf(), etc
|
||||||
#include <stdlib.h> // for srand()
|
#include <stdlib.h> // for srand()
|
||||||
#include <string.h> // for strrchr(), memset(), etc
|
#include <string.h> // for strrchr(), memset(), etc
|
||||||
|
|
@ -49,8 +51,8 @@ class NormMsgr
|
||||||
char* AccessBuffer()
|
char* AccessBuffer()
|
||||||
{return msg_buffer;}
|
{return msg_buffer;}
|
||||||
|
|
||||||
void ResetIndex()
|
void ResetIndex(unsigned int index = 0)
|
||||||
{msg_index = 0;}
|
{msg_index = index;}
|
||||||
void IncrementIndex(unsigned int count)
|
void IncrementIndex(unsigned int count)
|
||||||
{msg_index += count;}
|
{msg_index += count;}
|
||||||
unsigned int GetIndex() const
|
unsigned int GetIndex() const
|
||||||
|
|
@ -151,6 +153,15 @@ class NormMsgr
|
||||||
{return output_pending;}
|
{return output_pending;}
|
||||||
bool WriteOutput();
|
bool WriteOutput();
|
||||||
|
|
||||||
|
void OmitHeader(bool state)
|
||||||
|
{omit_header = state;}
|
||||||
|
|
||||||
|
// These can only be called post-OpenNormSession
|
||||||
|
void SetSilentReceiver(bool state)
|
||||||
|
{NormSetSilentReceiver(norm_session, true);}
|
||||||
|
void SetTxLoss(double txloss)
|
||||||
|
{NormSetTxLoss(norm_session, txloss);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_running;
|
bool is_running;
|
||||||
FILE* input_file; // stdin by default
|
FILE* input_file; // stdin by default
|
||||||
|
|
@ -159,6 +170,7 @@ class NormMsgr
|
||||||
MessageQueue input_msg_list; // list of enqueued messages (in norm sender cache)
|
MessageQueue input_msg_list; // list of enqueued messages (in norm sender cache)
|
||||||
|
|
||||||
NormSessionHandle norm_session;
|
NormSessionHandle norm_session;
|
||||||
|
bool is_multicast;
|
||||||
unsigned int norm_tx_queue_max; // max number of objects that can be enqueued at once
|
unsigned int norm_tx_queue_max; // max number of objects that can be enqueued at once
|
||||||
unsigned int norm_tx_queue_count; // count of unacknowledged enqueued objects (TBD - optionally track size too)
|
unsigned int norm_tx_queue_count; // count of unacknowledged enqueued objects (TBD - optionally track size too)
|
||||||
bool norm_tx_watermark_pending;
|
bool norm_tx_watermark_pending;
|
||||||
|
|
@ -170,14 +182,19 @@ class NormMsgr
|
||||||
bool output_pending;
|
bool output_pending;
|
||||||
Message* output_msg;
|
Message* output_msg;
|
||||||
MessageQueue output_msg_queue;
|
MessageQueue output_msg_queue;
|
||||||
|
// These are some options mainly for testing purposes
|
||||||
|
bool omit_header; // if "true", receive message length header is _not_ written to output
|
||||||
|
bool rx_silent;
|
||||||
|
double tx_loss;
|
||||||
|
|
||||||
}; // end class NormMsgr
|
}; // end class NormMsgr
|
||||||
|
|
||||||
NormMsgr::NormMsgr()
|
NormMsgr::NormMsgr()
|
||||||
: input_file(stdin), input_needed(true), input_msg(NULL),
|
: input_file(stdin), input_needed(false), input_msg(NULL),
|
||||||
norm_session(NORM_SESSION_INVALID), norm_tx_queue_max(2048), norm_tx_queue_count(0),
|
norm_session(NORM_SESSION_INVALID), is_multicast(false), norm_tx_queue_max(2048), norm_tx_queue_count(0),
|
||||||
norm_tx_watermark_pending(false), norm_tx_vacancy(true), norm_acking(false),
|
norm_tx_watermark_pending(false), norm_tx_vacancy(true), norm_acking(false),
|
||||||
output_file(stdout), output_ready(true), output_pending(false), output_msg(NULL)
|
output_file(stdout), output_ready(true), output_pending(false), output_msg(NULL),
|
||||||
|
omit_header(false), rx_silent(false), tx_loss(0.0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,12 +208,25 @@ NormMsgr::~NormMsgr()
|
||||||
|
|
||||||
bool NormMsgr::OpenNormSession(NormInstanceHandle instance, const char* addr, unsigned short port, NormNodeId nodeId)
|
bool NormMsgr::OpenNormSession(NormInstanceHandle instance, const char* addr, unsigned short port, NormNodeId nodeId)
|
||||||
{
|
{
|
||||||
|
if (NormIsUnicastAddress(addr))
|
||||||
|
is_multicast = false;
|
||||||
|
else
|
||||||
|
is_multicast = true;
|
||||||
norm_session = NormCreateSession(instance, addr, port, nodeId);
|
norm_session = NormCreateSession(instance, addr, port, nodeId);
|
||||||
if (NORM_SESSION_INVALID == norm_session)
|
if (NORM_SESSION_INVALID == norm_session)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "normMsgr error: unable to create NORM session\n");
|
fprintf(stderr, "normMsgr error: unable to create NORM session\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_multicast)
|
||||||
|
{
|
||||||
|
NormSetRxPortReuse(norm_session, true);
|
||||||
|
// TBD - make full loopback a command line option?
|
||||||
|
NormSetMulticastLoopback(norm_session, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set some default parameters (maybe we should put parameter setting in Start())
|
// Set some default parameters (maybe we should put parameter setting in Start())
|
||||||
NormSetRxCacheLimit(norm_session, norm_tx_queue_max);
|
NormSetRxCacheLimit(norm_session, norm_tx_queue_max);
|
||||||
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_ALL);
|
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_ALL);
|
||||||
|
|
@ -205,6 +235,9 @@ bool NormMsgr::OpenNormSession(NormInstanceHandle instance, const char* addr, un
|
||||||
NormSetTxCacheBounds(norm_session, 10*1024*1024, norm_tx_queue_max, norm_tx_queue_max);
|
NormSetTxCacheBounds(norm_session, 10*1024*1024, norm_tx_queue_max, norm_tx_queue_max);
|
||||||
|
|
||||||
//NormSetMessageTrace(norm_session, true);
|
//NormSetMessageTrace(norm_session, true);
|
||||||
|
|
||||||
|
NormSetTxRobustFactor(norm_session, 2);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // end NormMsgr::OpenNormSession()
|
} // end NormMsgr::OpenNormSession()
|
||||||
|
|
||||||
|
|
@ -268,6 +301,7 @@ bool NormMsgr::Start(bool sender, bool receiver)
|
||||||
if (receiver) NormStopReceiver(norm_session);
|
if (receiver) NormStopReceiver(norm_session);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
input_needed = true;
|
||||||
}
|
}
|
||||||
is_running = true;
|
is_running = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -379,6 +413,7 @@ bool NormMsgr::WriteOutput()
|
||||||
bufferPtr = output_msg->GetBuffer() + offset;
|
bufferPtr = output_msg->GetBuffer() + offset;
|
||||||
}
|
}
|
||||||
size_t result = fwrite(bufferPtr, 1, writeLength, output_file);
|
size_t result = fwrite(bufferPtr, 1, writeLength, output_file);
|
||||||
|
|
||||||
output_msg->IncrementIndex(result);
|
output_msg->IncrementIndex(result);
|
||||||
if (result < writeLength)
|
if (result < writeLength)
|
||||||
{
|
{
|
||||||
|
|
@ -389,6 +424,7 @@ bool NormMsgr::WriteOutput()
|
||||||
}
|
}
|
||||||
else if (ferror(input_file))
|
else if (ferror(input_file))
|
||||||
{
|
{
|
||||||
|
fprintf(stderr, "normMsgr: output error detected ...\n");
|
||||||
switch (errno)
|
switch (errno)
|
||||||
{
|
{
|
||||||
case EINTR:
|
case EINTR:
|
||||||
|
|
@ -406,12 +442,20 @@ bool NormMsgr::WriteOutput()
|
||||||
}
|
}
|
||||||
if (output_msg->IsComplete())
|
if (output_msg->IsComplete())
|
||||||
{
|
{
|
||||||
|
fflush(output_file);
|
||||||
delete output_msg;
|
delete output_msg;
|
||||||
output_msg = output_msg_queue.RemoveHead();
|
output_msg = output_msg_queue.RemoveHead();
|
||||||
if (NULL != output_msg)
|
if (NULL != output_msg)
|
||||||
output_msg->ResetIndex();
|
{
|
||||||
|
if (omit_header)
|
||||||
|
output_msg->ResetIndex(MSG_HEADER_SIZE);
|
||||||
|
else
|
||||||
|
output_msg->ResetIndex();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
output_pending = false;
|
output_pending = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -490,6 +534,7 @@ bool NormMsgr::EnqueueMessageObject()
|
||||||
|
|
||||||
void NormMsgr::HandleNormEvent(const NormEvent& event)
|
void NormMsgr::HandleNormEvent(const NormEvent& event)
|
||||||
{
|
{
|
||||||
|
bool logAllocs = false;
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
case NORM_TX_QUEUE_EMPTY:
|
case NORM_TX_QUEUE_EMPTY:
|
||||||
|
|
@ -528,6 +573,18 @@ void NormMsgr::HandleNormEvent(const NormEvent& event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NORM_REMOTE_SENDER_INACTIVE:
|
||||||
|
//fprintf(stderr, "REMOTE SENDER INACTIVE node: %u\n", NormNodeGetId(event.sender));
|
||||||
|
//NormNodeDelete(event.sender);
|
||||||
|
//logAllocs = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NORM_RX_OBJECT_ABORTED:
|
||||||
|
//fprintf(stderr, "NORM_RX_OBJECT_ABORTED\n");// %hu\n", NormObjectGetTransportId(event.object));
|
||||||
|
logAllocs = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case NORM_RX_OBJECT_COMPLETED:
|
case NORM_RX_OBJECT_COMPLETED:
|
||||||
{
|
{
|
||||||
char* data = NormDataDetachData(event.object);
|
char* data = NormDataDetachData(event.object);
|
||||||
|
|
@ -536,7 +593,7 @@ void NormMsgr::HandleNormEvent(const NormEvent& event)
|
||||||
Message* msg = new Message(data, NormObjectGetSize(event.object));
|
Message* msg = new Message(data, NormObjectGetSize(event.object));
|
||||||
if (NULL == msg)
|
if (NULL == msg)
|
||||||
{
|
{
|
||||||
perror("normMsgr new receive Message error");
|
perror("normMsgr: new Message() error");
|
||||||
delete[] data; // TBD - may need to finally implement NormDelete() function!
|
delete[] data; // TBD - may need to finally implement NormDelete() function!
|
||||||
// TBD Stop() as a fatal out of memory error?
|
// TBD Stop() as a fatal out of memory error?
|
||||||
break;
|
break;
|
||||||
|
|
@ -544,7 +601,10 @@ void NormMsgr::HandleNormEvent(const NormEvent& event)
|
||||||
if (NULL == output_msg)
|
if (NULL == output_msg)
|
||||||
{
|
{
|
||||||
output_msg = msg;
|
output_msg = msg;
|
||||||
output_msg->ResetIndex();
|
if (omit_header)
|
||||||
|
output_msg->ResetIndex(MSG_HEADER_SIZE);
|
||||||
|
else
|
||||||
|
output_msg->ResetIndex();
|
||||||
output_pending = true;
|
output_pending = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -559,13 +619,23 @@ void NormMsgr::HandleNormEvent(const NormEvent& event)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//NormReleasePreviousEvent(NormGetInstance(norm_session));
|
||||||
|
|
||||||
|
if (logAllocs)
|
||||||
|
{
|
||||||
|
#ifdef USE_PROTO_CHECK
|
||||||
|
ProtoCheckLogAllocations(stderr);
|
||||||
|
#endif // USE_PROTO_CHECK
|
||||||
|
}
|
||||||
|
|
||||||
} // end NormMsgr::HandleNormEvent()
|
} // end NormMsgr::HandleNormEvent()
|
||||||
|
|
||||||
|
|
||||||
void Usage()
|
void Usage()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: normMsgr id <nodeId> {send &| recv} [addr <addr>[/<port>]][ack <node1>[,<node2>,...]\n"
|
fprintf(stderr, "Usage: normMsgr id <nodeId> {send &| recv} [addr <addr>[/<port>]][ack <node1>[,<node2>,...]\n"
|
||||||
" [cc|cce|ccl|rate <bitsPerSecond>][interface <name>][debug <level>][trace]\n");
|
" [cc|cce|ccl|rate <bitsPerSecond>][interface <name>][debug <level>][trace]\n"
|
||||||
|
" [omit][silent][txloss <lossFraction>]\n");
|
||||||
}
|
}
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|
@ -587,6 +657,9 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
int debugLevel = 0;
|
int debugLevel = 0;
|
||||||
bool trace = false;
|
bool trace = false;
|
||||||
|
bool omitHeaderOnOutput = false;
|
||||||
|
bool silentReceiver = false;
|
||||||
|
double txloss = 0.0;
|
||||||
|
|
||||||
// Parse command-line
|
// Parse command-line
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
@ -700,6 +773,23 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
mcastIface = argv[i++];
|
mcastIface = argv[i++];
|
||||||
}
|
}
|
||||||
|
else if (0 == strncmp(cmd, "omit", len))
|
||||||
|
{
|
||||||
|
omitHeaderOnOutput = true;
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "silent", len))
|
||||||
|
{
|
||||||
|
silentReceiver = true;
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "txloss", len))
|
||||||
|
{
|
||||||
|
if (1 != sscanf(argv[i++], "%lf", &txloss))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "nodeMsgr error: invalid 'txloss' value!\n");
|
||||||
|
Usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (0 == strncmp(cmd, "debug", len))
|
else if (0 == strncmp(cmd, "debug", len))
|
||||||
{
|
{
|
||||||
if (i >= argc)
|
if (i >= argc)
|
||||||
|
|
@ -746,6 +836,8 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
NormMsgr normMsgr;
|
NormMsgr normMsgr;
|
||||||
|
|
||||||
|
if (omitHeaderOnOutput) normMsgr.OmitHeader(true);
|
||||||
|
|
||||||
if (!normMsgr.OpenNormSession(normInstance, sessionAddr, sessionPort, (NormNodeId)nodeId))
|
if (!normMsgr.OpenNormSession(normInstance, sessionAddr, sessionPort, (NormNodeId)nodeId))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "normMsgr error: unable to open NORM session\n");
|
fprintf(stderr, "normMsgr error: unable to open NORM session\n");
|
||||||
|
|
@ -753,6 +845,10 @@ int main(int argc, char* argv[])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (silentReceiver) normMsgr.SetSilentReceiver(true);
|
||||||
|
if (txloss > 0.0) normMsgr.SetTxLoss(txloss);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ackingNodeCount; i++)
|
for (unsigned int i = 0; i < ackingNodeCount; i++)
|
||||||
normMsgr.AddAckingNode(ackingNodeList[i]);
|
normMsgr.AddAckingNode(ackingNodeList[i]);
|
||||||
|
|
||||||
|
|
@ -848,6 +944,9 @@ int main(int argc, char* argv[])
|
||||||
normMsgr.WriteOutput(); // TBD - implement output async i/o notification as needed
|
normMsgr.WriteOutput(); // TBD - implement output async i/o notification as needed
|
||||||
|
|
||||||
} // end while(normMsgr.IsRunning()
|
} // end while(normMsgr.IsRunning()
|
||||||
|
|
||||||
|
fprintf(stderr, "normMsgr exiting ...\n");
|
||||||
|
|
||||||
NormDestroyInstance(normInstance);
|
NormDestroyInstance(normInstance);
|
||||||
} // end main()
|
} // end main()
|
||||||
|
|
||||||
|
|
@ -865,6 +964,8 @@ NormMsgr::Message::Message(char* buffer, unsigned int size)
|
||||||
uint16_t msgSize = size + MSG_HEADER_SIZE;
|
uint16_t msgSize = size + MSG_HEADER_SIZE;
|
||||||
msgSize = htons(msgSize);
|
msgSize = htons(msgSize);
|
||||||
memcpy(msg_header, &msgSize, MSG_HEADER_SIZE);
|
memcpy(msg_header, &msgSize, MSG_HEADER_SIZE);
|
||||||
|
|
||||||
|
fprintf(stderr, "output msg ctor data = %.20s\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
NormMsgr::Message::~Message()
|
NormMsgr::Message::~Message()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,463 @@
|
||||||
|
|
||||||
|
// This example NORM application acts as unicast "server". A NORM receive-only session "listens"
|
||||||
|
// on a "serverPort". When new remote senders are detected, the sender is assigned to a
|
||||||
|
// newly create "client" NormSession that is "connected" to the remote sender/client addr/port.
|
||||||
|
// The NormSetRxPortReuse() call provides an option to "connect" the underlying NORM UDP socket
|
||||||
|
// to the remote sender/client address/port. Note this is not yet supported for NORM-CCE (ECN)
|
||||||
|
// congestion control operation.
|
||||||
|
|
||||||
|
// By creating "client" NormSessions for each client connection, this enables multiple clients
|
||||||
|
// from the same host (with the same NormNodeId to connect to the server at the same time.
|
||||||
|
// Otherwise, clients with the same NormNodeId would "collide" at the server receive session.
|
||||||
|
// Even the approach here is not perfect as a packet from a another client instance with the
|
||||||
|
// same NormNodeId might change the given "remote sender" source addr/port before the
|
||||||
|
// connected "client" session is created as a sort of race condition.
|
||||||
|
// A potential enhancement to NORM would be to allow tracking of multiple remote senders
|
||||||
|
// with the same NormNodeId but different instanceIds ...
|
||||||
|
|
||||||
|
// BUILD: (assumes "normApi.h" in "include" ...
|
||||||
|
// g++ -I../include -o normServer normServer.cpp normSocket.cpp ../lib/libnorm.a ../protolib/lib/libprotokit.a -lresolv
|
||||||
|
|
||||||
|
|
||||||
|
// EXAMPLE NOTES:
|
||||||
|
//
|
||||||
|
// 0) THIS IS A WORK IN PROGRESS AND NOT YET FUNCTIONAL!
|
||||||
|
//
|
||||||
|
// 1) Some of the functions here may be added to the NORM API in the future.
|
||||||
|
//
|
||||||
|
// 2) The "main()" below is a single-threaded example with a single NormInstance and a
|
||||||
|
// single NormGetNextEvent() main loop. Note that the NormAccept() call allows for a
|
||||||
|
// new instance (and hence new NormDescriptor) for each accepted client, so multiple
|
||||||
|
// threads or event thread-pooling versions of this could be implemented for
|
||||||
|
// performance or application design purposes. A future version of the NORM API and
|
||||||
|
// this could even provide for very "socket-like" API calls where each "client"
|
||||||
|
// session has its own descriptor independent of threading (e.g. a "normSocket.h" API
|
||||||
|
// that is implemented around the current low level NORM API). This sort of "NORM
|
||||||
|
// socket" approach could be supported for unicast and SSM streams without too much
|
||||||
|
// difficulty.
|
||||||
|
|
||||||
|
#include "normSocket.h"
|
||||||
|
#include <arpa/inet.h> // for inet_ntoa
|
||||||
|
#include <stdio.h> // for fprintf()
|
||||||
|
#include <string.h> // for memcmp()
|
||||||
|
#include <map> // for std::map<>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <fcntl.h> // for, well, fnctl()
|
||||||
|
#include <errno.h> // obvious child
|
||||||
|
|
||||||
|
// Our "server" indexes clients by their source addr/port
|
||||||
|
class ClientInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientInfo(UINT8 ipVersion = 0, const char* theAddr = NULL, UINT16 thePort = 0);
|
||||||
|
bool operator < (const ClientInfo& a) const;
|
||||||
|
|
||||||
|
int GetAddressFamily() const;
|
||||||
|
const char* GetAddress() const
|
||||||
|
{return client_addr;}
|
||||||
|
UINT16 GetPort() const
|
||||||
|
{return client_port;}
|
||||||
|
|
||||||
|
const char* GetAddressString() const;
|
||||||
|
void Print(FILE* filePtr) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 addr_version; // 4 or 6
|
||||||
|
char client_addr[16]; // big enough for IPv6
|
||||||
|
UINT16 client_port;
|
||||||
|
|
||||||
|
}; // end class ClientInfo
|
||||||
|
|
||||||
|
|
||||||
|
ClientInfo::ClientInfo(UINT8 addrVersion, const char* clientAddr, UINT16 clientPort)
|
||||||
|
: addr_version(addrVersion), client_port(clientPort)
|
||||||
|
{
|
||||||
|
if (NULL == clientAddr) addrVersion = 0; // forces zero initialization
|
||||||
|
switch (addrVersion)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
memcpy(client_addr, clientAddr, 4);
|
||||||
|
memset(client_addr+4, 0, 12);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
memcpy(client_addr, clientAddr, 16);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memset(client_addr, 0, 16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns "true" if "this" less than "a" (used by C++ map)
|
||||||
|
bool ClientInfo::operator <(const ClientInfo& a) const
|
||||||
|
{
|
||||||
|
if (addr_version != a.addr_version)
|
||||||
|
return (addr_version < a.addr_version);
|
||||||
|
else if (client_port != a.client_port)
|
||||||
|
return (client_port < a.client_port);
|
||||||
|
else if (4 == addr_version)
|
||||||
|
return (0 > memcmp(client_addr, a.client_addr, 4));
|
||||||
|
else
|
||||||
|
return (0 > memcmp(client_addr, a.client_addr, 16));
|
||||||
|
} // end ClientInfo::operator <()
|
||||||
|
|
||||||
|
int ClientInfo::GetAddressFamily() const
|
||||||
|
{
|
||||||
|
if (4 == addr_version)
|
||||||
|
return AF_INET;
|
||||||
|
else
|
||||||
|
return AF_INET6;
|
||||||
|
} // end ClientInfo::GetAddressFamily()
|
||||||
|
|
||||||
|
|
||||||
|
const char* ClientInfo::GetAddressString() const
|
||||||
|
{
|
||||||
|
static char text[64];
|
||||||
|
text[63] = '\0';
|
||||||
|
int addrFamily;
|
||||||
|
if (4 == addr_version)
|
||||||
|
addrFamily = AF_INET;
|
||||||
|
else
|
||||||
|
addrFamily = AF_INET6;
|
||||||
|
inet_ntop(addrFamily, client_addr, text, 63);
|
||||||
|
return text;
|
||||||
|
} // end ClientInfo::GetAddressString()
|
||||||
|
|
||||||
|
void ClientInfo::Print(FILE* filePtr) const
|
||||||
|
{
|
||||||
|
char text[64];
|
||||||
|
text[63] = '\0';
|
||||||
|
int addrFamily;
|
||||||
|
if (4 == addr_version)
|
||||||
|
addrFamily = AF_INET;
|
||||||
|
else
|
||||||
|
addrFamily = AF_INET6;
|
||||||
|
inet_ntop(addrFamily, client_addr, text, 63);
|
||||||
|
fprintf(filePtr, "%s/%hu", text, client_port);
|
||||||
|
} // end ClientInfo::Print()
|
||||||
|
|
||||||
|
|
||||||
|
// C++ map used to index client sessions by the client source addr/port
|
||||||
|
typedef std::map<ClientInfo, NormSocketHandle> ClientMap;
|
||||||
|
|
||||||
|
ClientInfo NormGetClientInfo(NormNodeHandle client)
|
||||||
|
{
|
||||||
|
char addr[16]; // big enough for IPv6
|
||||||
|
unsigned int addrLen = 16;
|
||||||
|
UINT16 port;
|
||||||
|
NormNodeGetAddress(client, addr, &addrLen, &port);
|
||||||
|
int addrFamily;
|
||||||
|
UINT8 version;
|
||||||
|
if (4 == addrLen)
|
||||||
|
{
|
||||||
|
addrFamily = AF_INET;
|
||||||
|
version = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addrFamily = AF_INET6;
|
||||||
|
version = 6;
|
||||||
|
}
|
||||||
|
return ClientInfo(version, addr, port);
|
||||||
|
} // end NormGetClientInfo()
|
||||||
|
|
||||||
|
NormSocketHandle FindClientSocket(ClientMap& clientMap, const ClientInfo& clientInfo)
|
||||||
|
{
|
||||||
|
ClientMap::iterator it = clientMap.find(clientInfo);
|
||||||
|
if (clientMap.end() != it)
|
||||||
|
return &(it->second);
|
||||||
|
else
|
||||||
|
return NORM_SOCKET_INVALID;
|
||||||
|
} // end FindClientSocket()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
ClientMap clientMap;
|
||||||
|
|
||||||
|
UINT16 serverPort = 5000;
|
||||||
|
UINT16 serverInstanceId = 1;
|
||||||
|
char groupAddr[64];
|
||||||
|
const char* groupAddrPtr = NULL;
|
||||||
|
const char* mcastInterface = NULL;
|
||||||
|
|
||||||
|
bool trace = false;
|
||||||
|
unsigned int debugLevel = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
const char* cmd = argv[i];
|
||||||
|
unsigned int len = strlen(cmd);
|
||||||
|
if (0 == strncmp(cmd, "listen", len))
|
||||||
|
{
|
||||||
|
// listen [<groupAddr>/]<port>
|
||||||
|
const char* val = argv[++i];
|
||||||
|
const char* portPtr = strchr(val, '/');
|
||||||
|
if (NULL != portPtr)
|
||||||
|
portPtr++;
|
||||||
|
else
|
||||||
|
portPtr = val;
|
||||||
|
unsigned int addrTextLen = portPtr - val;
|
||||||
|
if (addrTextLen > 0)
|
||||||
|
{
|
||||||
|
addrTextLen -= 1;
|
||||||
|
strncpy(groupAddr, val, addrTextLen);
|
||||||
|
groupAddr[addrTextLen] = '\0';
|
||||||
|
groupAddrPtr = groupAddr;
|
||||||
|
}
|
||||||
|
if (1 != sscanf(portPtr, "%hu", &serverPort))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer error: invalid <port> \"%s\"\n", portPtr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "interface", len))
|
||||||
|
{
|
||||||
|
mcastInterface = argv[++i];
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "trace", len))
|
||||||
|
{
|
||||||
|
trace = true;
|
||||||
|
}
|
||||||
|
else if (0 == strncmp(cmd, "debug", len))
|
||||||
|
{
|
||||||
|
if (1 != sscanf(argv[++i], "%u", &debugLevel))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer error: invalid debug level\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer error: invalid command \"%s\"\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For unicast operation in this demo app, the server only "talks back"
|
||||||
|
// to one client on a first come, first serve basis. (Multiple clients
|
||||||
|
// can connect and send data _to_ the server, but in this simple example,
|
||||||
|
// the server only sends to one at a time. For the multicast server case,
|
||||||
|
// the server multicasts to the entire group.
|
||||||
|
NormSocketHandle firstClientSocket = NORM_SOCKET_INVALID;
|
||||||
|
|
||||||
|
NormInstanceHandle instance = NormCreateInstance();
|
||||||
|
|
||||||
|
NormSocketHandle serverSocket = NormListen(instance, serverPort, groupAddrPtr);
|
||||||
|
|
||||||
|
if (trace) NormSetMessageTrace(NormGetSession(serverSocket), true);
|
||||||
|
if (0 != debugLevel) NormSetDebugLevel(debugLevel);
|
||||||
|
|
||||||
|
//NormSetDebugLevel(8);
|
||||||
|
//NormSetMessageTrace(NormGetSession(serverSocket), true);
|
||||||
|
|
||||||
|
// We use a select() call to multiplex input reading and NormSocket handling
|
||||||
|
fd_set fdset;
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
|
||||||
|
// Get our input (STDIN) descriptor and set non-blocking
|
||||||
|
FILE* inputFile = stdin;
|
||||||
|
int inputfd = fileno(inputFile);
|
||||||
|
if (-1 == fcntl(inputfd, F_SETFL, fcntl(inputfd, F_GETFL, 0) | O_NONBLOCK))
|
||||||
|
perror("normClient: fcntl(inputfd, O_NONBLOCK) error");
|
||||||
|
// Get our NormInstance descriptor
|
||||||
|
int normfd = NormGetDescriptor(instance);
|
||||||
|
bool keepGoing = true;
|
||||||
|
bool writeReady = false;
|
||||||
|
unsigned int inputLength = 0;
|
||||||
|
unsigned int bytesWritten = 0;
|
||||||
|
const unsigned int BUFFER_LENGTH = 2048;
|
||||||
|
char inputBuffer[BUFFER_LENGTH];
|
||||||
|
bool inputNeeded = false; // will be set to "true" upon CONNECT
|
||||||
|
while (keepGoing)
|
||||||
|
{
|
||||||
|
FD_SET(normfd, &fdset);
|
||||||
|
int maxfd = normfd;
|
||||||
|
if (inputNeeded)
|
||||||
|
{
|
||||||
|
FD_SET(inputfd, &fdset);
|
||||||
|
if (inputfd > maxfd) maxfd = inputfd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FD_CLR(inputfd, &fdset);
|
||||||
|
}
|
||||||
|
int result = select(maxfd+1, &fdset, NULL, NULL, NULL);
|
||||||
|
if (result <= 0)
|
||||||
|
{
|
||||||
|
perror("normClient: select() error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(inputfd, &fdset))
|
||||||
|
{
|
||||||
|
// Read input into our txBuffer
|
||||||
|
inputLength = fread(inputBuffer, 1, BUFFER_LENGTH, inputFile);
|
||||||
|
if (inputLength > 0)
|
||||||
|
{
|
||||||
|
// We got our input
|
||||||
|
bytesWritten = 0;
|
||||||
|
inputNeeded = false;
|
||||||
|
}
|
||||||
|
else if (feof(inputFile))
|
||||||
|
{
|
||||||
|
// TBD - initiate server shutdown if it's job is
|
||||||
|
// only until the input is closed
|
||||||
|
// Meanwhile, we just stick around to receive stuff from the clients
|
||||||
|
inputNeeded = false; // TBD - should also fclose(inputFile)??
|
||||||
|
}
|
||||||
|
else if (ferror(inputFile))
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EINTR:
|
||||||
|
// interupted, try again
|
||||||
|
break;
|
||||||
|
case EAGAIN:
|
||||||
|
// input starved, wait for next notification
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
perror("normClient: error reading input");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FD_ISSET(normfd, &fdset))
|
||||||
|
{
|
||||||
|
|
||||||
|
// There's a NORM event pending
|
||||||
|
NormSocketEvent event;
|
||||||
|
if (NormGetSocketEvent(instance, &event))
|
||||||
|
{
|
||||||
|
ClientInfo clientInfo;
|
||||||
|
if (NORM_NODE_INVALID != event.sender)
|
||||||
|
clientInfo = NormGetClientInfo(event.sender);
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case NORM_SOCKET_ACCEPT:
|
||||||
|
{
|
||||||
|
if (event.socket == serverSocket)
|
||||||
|
{
|
||||||
|
// Possibly a new "client" connecting to our "server"
|
||||||
|
// First confirm that this really is a new client.
|
||||||
|
if (NORM_SOCKET_INVALID != FindClientSocket(clientMap, clientInfo))
|
||||||
|
{
|
||||||
|
// We think we're already connected to this client
|
||||||
|
fprintf(stderr, "normServer: duplicative %s client ...\n",
|
||||||
|
(NORM_REMOTE_SENDER_NEW == event.event.type) ? "new" : "reset");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NormSocketHandle clientSocket = NormAccept(serverSocket, event.sender);
|
||||||
|
|
||||||
|
// TBD - For multicast, if we are sending a tx_stream, we could flush it here to
|
||||||
|
// bring the new receiver "up to date" ... probably would be best to
|
||||||
|
// do this on some sort of timer-basis in the case of a bunch of receivers
|
||||||
|
// joining in a short window of time ...
|
||||||
|
|
||||||
|
if (trace) // note we're already tracing the mcast session
|
||||||
|
NormSetMessageTrace(NormGetSession(clientSocket), true);
|
||||||
|
//NormSetMessageTrace(NormGetSession(clientSocket), true);
|
||||||
|
clientMap[clientInfo] = clientSocket;
|
||||||
|
fprintf(stderr, "normServer: ACCEPTED connection from %s/%hu\n",
|
||||||
|
clientInfo.GetAddressString(), clientInfo.GetPort());
|
||||||
|
// We have at least one client, so lets serve up some juicy input
|
||||||
|
inputNeeded = true;
|
||||||
|
writeReady = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// shouldn't happen
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_CONNECT:
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer: CONNECTED to %s/%hu ...\n",
|
||||||
|
clientInfo.GetAddressString(), clientInfo.GetPort());
|
||||||
|
if (NORM_SOCKET_INVALID == firstClientSocket)
|
||||||
|
firstClientSocket = event.socket;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_READ:
|
||||||
|
{
|
||||||
|
// This is a cue to try to read data from stream
|
||||||
|
// For our test app here, the data is read and output to STDOUT
|
||||||
|
bool rxReady = true;
|
||||||
|
while (rxReady)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
ssize_t bytesRead = NormRead(event.socket, buffer, 1024);
|
||||||
|
if (bytesRead < 0)
|
||||||
|
{
|
||||||
|
// This shouldn't happen with ack-based flow control used
|
||||||
|
fprintf(stderr, "normServer: broken stream ...\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bytesRead > 0)
|
||||||
|
fwrite(buffer, sizeof(char), bytesRead, stdout);
|
||||||
|
if (bytesRead < 1024) rxReady = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_WRITE:
|
||||||
|
// We only demo server data transmission for the multicast server case
|
||||||
|
// (see comment below)
|
||||||
|
if ((NULL != groupAddrPtr) || (event.socket == firstClientSocket))
|
||||||
|
writeReady = true;
|
||||||
|
break;
|
||||||
|
case NORM_SOCKET_CLOSING:
|
||||||
|
fprintf(stderr, "normServer: client %s/%hu CLOSING connection ...\n",
|
||||||
|
clientInfo.GetAddressString(), clientInfo.GetPort());
|
||||||
|
if (event.socket == firstClientSocket)
|
||||||
|
firstClientSocket = NORM_SOCKET_INVALID;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NORM_SOCKET_CLOSED:
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer: connection to client %s/%hu CLOSED ...\n",
|
||||||
|
clientInfo.GetAddressString(), clientInfo.GetPort());
|
||||||
|
if (event.socket == firstClientSocket)
|
||||||
|
firstClientSocket = NORM_SOCKET_INVALID;
|
||||||
|
clientMap.erase(clientInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NORM_SOCKET_NONE:
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
} // end switch(event.type)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "normServer: NormGetNextSocketEvent() returned false\n");
|
||||||
|
}
|
||||||
|
} // end if FD_ISSET(normfd)
|
||||||
|
|
||||||
|
// For our _multicast_ "normServer" example, the server can send to the group
|
||||||
|
// (For a unicast "normServer", we would need to do something more complex
|
||||||
|
// to manage sending data to each individual client that connects to us.
|
||||||
|
// So, for the moment, the unicast "normServer" only sends to the "firstClientSocket"
|
||||||
|
NormSocketHandle sendSocket = (NULL != groupAddrPtr) ? serverSocket : firstClientSocket;
|
||||||
|
if (NORM_SOCKET_INVALID != sendSocket)
|
||||||
|
{
|
||||||
|
if (writeReady && (inputLength > 0))
|
||||||
|
{
|
||||||
|
// We have data in our inputBuffer and the NormSocket is "writeReady", so send it
|
||||||
|
bytesWritten += NormWrite(sendSocket, inputBuffer + bytesWritten, inputLength - bytesWritten);
|
||||||
|
if (bytesWritten < inputLength)
|
||||||
|
{
|
||||||
|
// Couldn't write whole inputBuffer, need to wait for NORM_SOCKET_WRITE event
|
||||||
|
writeReady = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// inputBuffer has been completely written
|
||||||
|
inputLength = 0;
|
||||||
|
inputNeeded = true;
|
||||||
|
NormFlush(sendSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end while (keepGoing)
|
||||||
|
} // end main()
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,120 @@
|
||||||
|
|
||||||
|
#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
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#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 = NORM_INSTANCE_INVALID);
|
||||||
|
|
||||||
|
NormSocketHandle NormListen(NormInstanceHandle instance, UINT16 serverPort, const char* groupAddr = NULL);
|
||||||
|
|
||||||
|
NormSocketHandle NormConnect(NormInstanceHandle instance,
|
||||||
|
const char* serverAddr,
|
||||||
|
UINT16 serverPort,
|
||||||
|
const char* groupAddr = NULL,
|
||||||
|
NormNodeId clientId = NORM_NODE_NONE);
|
||||||
|
|
||||||
|
NormSocketHandle NormAccept(NormSocketHandle serverSocket, NormNodeHandle clientNode, NormInstanceHandle instance = NORM_INSTANCE_INVALID);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Helper API functions
|
||||||
|
|
||||||
|
NormSessionHandle NormGetSession(NormSocketHandle normSocket);
|
||||||
|
NormSessionHandle NormGetMulticastSession(NormSocketHandle normSocket);
|
||||||
|
|
||||||
|
typedef enum NormSocketEventType
|
||||||
|
{
|
||||||
|
NORM_SOCKET_NONE = 0,
|
||||||
|
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_CLOSED // indicates socket is now closed (invalid for further operations)
|
||||||
|
} NormSocketEventType;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
bool NormGetSocketEvent(NormInstanceHandle normInstance, NormSocketEvent* event, bool waitForEvent = true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !_NORM_SOCKET
|
||||||
|
|
@ -173,6 +173,8 @@ typedef enum NormEventType
|
||||||
NORM_TX_RATE_CHANGED,
|
NORM_TX_RATE_CHANGED,
|
||||||
NORM_LOCAL_SENDER_CLOSED,
|
NORM_LOCAL_SENDER_CLOSED,
|
||||||
NORM_REMOTE_SENDER_NEW,
|
NORM_REMOTE_SENDER_NEW,
|
||||||
|
NORM_REMOTE_SENDER_RESET, // remote sender instanceId or FEC params changed
|
||||||
|
NORM_REMOTE_SENDER_ADDRESS, // remote sender src addr and/or port changed
|
||||||
NORM_REMOTE_SENDER_ACTIVE,
|
NORM_REMOTE_SENDER_ACTIVE,
|
||||||
NORM_REMOTE_SENDER_INACTIVE,
|
NORM_REMOTE_SENDER_INACTIVE,
|
||||||
NORM_REMOTE_SENDER_PURGED, // not yet implemented
|
NORM_REMOTE_SENDER_PURGED, // not yet implemented
|
||||||
|
|
@ -184,7 +186,10 @@ typedef enum NormEventType
|
||||||
NORM_RX_OBJECT_ABORTED,
|
NORM_RX_OBJECT_ABORTED,
|
||||||
NORM_GRTT_UPDATED,
|
NORM_GRTT_UPDATED,
|
||||||
NORM_CC_ACTIVE,
|
NORM_CC_ACTIVE,
|
||||||
NORM_CC_INACTIVE
|
NORM_CC_INACTIVE,
|
||||||
|
NORM_ACKING_NODE_NEW, // whe NormSetAutoAcking xxx
|
||||||
|
NORM_SEND_ERROR, // ICMP error (e.g. destination unreachable)
|
||||||
|
NORM_USER_TIMEOUT // issues when timeout set by NormSetUserTimer() expires
|
||||||
} NormEventType;
|
} NormEventType;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -222,7 +227,6 @@ NORM_API_LINKAGE
|
||||||
void NormResumeInstance(NormInstanceHandle instanceHandle);
|
void NormResumeInstance(NormInstanceHandle instanceHandle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This MUST be set to enable NORM_OBJECT_FILE reception!
|
// This MUST be set to enable NORM_OBJECT_FILE reception!
|
||||||
// (otherwise received files are ignored)
|
// (otherwise received files are ignored)
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
|
|
@ -263,6 +267,9 @@ NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormDestroySession(NormSessionHandle sessionHandle);
|
void NormDestroySession(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
NormInstanceHandle NormGetInstance(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormIsUnicastAddress(const char* address);
|
bool NormIsUnicastAddress(const char* address);
|
||||||
|
|
||||||
|
|
@ -272,10 +279,19 @@ void NormSetUserData(NormSessionHandle sessionHandle, const void* userData);
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
const void* NormGetUserData(NormSessionHandle sessionHandle);
|
const void* NormGetUserData(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormSetUserTimer(NormSessionHandle sessionHandle, double seconds);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormCancelUserTimer(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
|
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
UINT16 NormGetRxPort(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetTxPort(NormSessionHandle sessionHandle,
|
bool NormSetTxPort(NormSessionHandle sessionHandle,
|
||||||
UINT16 txPortNumber,
|
UINT16 txPortNumber,
|
||||||
|
|
@ -291,12 +307,13 @@ void NormSetTxOnly(NormSessionHandle sessionHandle,
|
||||||
bool connectToSessionAddress DEFAULT(false));
|
bool connectToSessionAddress DEFAULT(false));
|
||||||
|
|
||||||
|
|
||||||
// This does not affect the rx_socket binding if already bound
|
// This does not affect the rx_socket binding if already bound (sender or receiver already started)
|
||||||
// (i.e., just affects where NORM packets are sent)
|
// (i.e., just affects where NORM packets are sent)
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormChangeDestination(NormSessionHandle sessionHandle,
|
bool NormChangeDestination(NormSessionHandle sessionHandle,
|
||||||
const char* sessionAddress,
|
const char* sessionAddress,
|
||||||
UINT16 sessionPort);
|
UINT16 sessionPort,
|
||||||
|
bool connectToSessionAddress DEFAULT(false));
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormSetRxPortReuse(NormSessionHandle sessionHandle,
|
void NormSetRxPortReuse(NormSessionHandle sessionHandle,
|
||||||
|
|
@ -319,6 +336,10 @@ NORM_API_LINKAGE
|
||||||
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
|
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
|
||||||
const char* interfaceName);
|
const char* interfaceName);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
bool NormSetSSM(NormSessionHandle sessionHandle,
|
||||||
|
const char* sourceAddress);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetTTL(NormSessionHandle sessionHandle,
|
bool NormSetTTL(NormSessionHandle sessionHandle,
|
||||||
unsigned char ttl);
|
unsigned char ttl);
|
||||||
|
|
@ -331,6 +352,10 @@ NORM_API_LINKAGE
|
||||||
bool NormSetLoopback(NormSessionHandle sessionHandle,
|
bool NormSetLoopback(NormSessionHandle sessionHandle,
|
||||||
bool loopback);
|
bool loopback);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
bool NormSetMulticastLoopback(NormSessionHandle sessionHandle,
|
||||||
|
bool loopback);
|
||||||
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetFragmentation(NormSessionHandle sessionHandle,
|
bool NormSetFragmentation(NormSessionHandle sessionHandle,
|
||||||
|
|
@ -375,13 +400,17 @@ double NormGetReportInterval(NormSessionHandle sessionHandle);
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
NormSessionId NormGetRandomSessionId();
|
NormSessionId NormGetRandomSessionId();
|
||||||
|
|
||||||
|
|
||||||
|
// This function has been updated so that 16-bit Reed-Solomon
|
||||||
|
// codecs can be accessed. This may cause an issue for linking
|
||||||
|
// to older versions of the NORM library
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormStartSender(NormSessionHandle sessionHandle,
|
bool NormStartSender(NormSessionHandle sessionHandle,
|
||||||
NormSessionId instanceId,
|
NormSessionId instanceId,
|
||||||
UINT32 bufferSpace,
|
UINT32 bufferSpace,
|
||||||
UINT16 segmentSize,
|
UINT16 segmentSize,
|
||||||
unsigned char numData,
|
UINT16 numData,
|
||||||
unsigned char numParity);
|
UINT16 numParity);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormStopSender(NormSessionHandle sessionHandle);
|
void NormStopSender(NormSessionHandle sessionHandle);
|
||||||
|
|
@ -529,6 +558,10 @@ NORM_API_LINKAGE
|
||||||
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
||||||
NormNodeId nodeId);
|
NormNodeId nodeId);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
NormNodeHandle NormGetAckingNodeHandle(NormSessionHandle sessionHandle,
|
||||||
|
NormNodeId nodeId);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormSetAutoAckingNodes(NormSessionHandle sessionHandle,
|
void NormSetAutoAckingNodes(NormSessionHandle sessionHandle,
|
||||||
NormTrackingStatus trackingStatus);
|
NormTrackingStatus trackingStatus);
|
||||||
|
|
@ -540,7 +573,7 @@ NormAckingStatus NormGetAckingStatus(NormSessionHandle sessionHandle,
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormGetNextAckingNode(NormSessionHandle sessionHandle,
|
bool NormGetNextAckingNode(NormSessionHandle sessionHandle,
|
||||||
NormNodeId* nodeId,
|
NormNodeId* nodeId,
|
||||||
NormAckingStatus* ackingStatus);
|
NormAckingStatus* ackingStatus DEFAULT(0));
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSendCommand(NormSessionHandle sessionHandle,
|
bool NormSendCommand(NormSessionHandle sessionHandle,
|
||||||
|
|
@ -687,6 +720,12 @@ bool NormNodeGetAddress(NormNodeHandle nodeHandle,
|
||||||
unsigned int* bufferLen,
|
unsigned int* bufferLen,
|
||||||
UINT16* port DEFAULT((UINT16*)0));
|
UINT16* port DEFAULT((UINT16*)0));
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormNodeSetUserData(NormNodeHandle nodeHandle, const void* userData);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
const void* NormNodeGetUserData(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
double NormNodeGetGrtt(NormNodeHandle remoteSender);
|
double NormNodeGetGrtt(NormNodeHandle remoteSender);
|
||||||
|
|
||||||
|
|
@ -702,7 +741,22 @@ void NormNodeFreeBuffers(NormNodeHandle remoteSender);
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormNodeDelete(NormNodeHandle remoteSender);
|
void NormNodeDelete(NormNodeHandle remoteSender);
|
||||||
|
|
||||||
// The next 4 functions have not yet been implemented
|
NORM_API_LINKAGE
|
||||||
|
void NormNodeRetain(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormNodeRelease(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
|
/** Some experimental functions */
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormReleasePreviousEvent(NormInstanceHandle instanceHandle);
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
UINT32 NormCountCompletedObjects(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
|
||||||
|
// The next functions have _not_ yet been implemented
|
||||||
// (work in progress)
|
// (work in progress)
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormNodeSetAutoDelete(NormNodeHandle remoteSender,
|
void NormNodeSetAutoDelete(NormNodeHandle remoteSender,
|
||||||
|
|
@ -714,18 +768,6 @@ bool NormNodeAllowSender(NormNodeId senderId);
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormNodeDenySender(NormNodeId senderId);
|
bool NormNodeDenySender(NormNodeId senderId);
|
||||||
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
|
||||||
void NormNodeRetain(NormNodeHandle nodeHandle);
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
|
||||||
void NormNodeRelease(NormNodeHandle nodeHandle);
|
|
||||||
|
|
||||||
/** Some experimental functions */
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
|
||||||
UINT32 NormCountCompletedObjects(NormSessionHandle sessionHandle);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // end extern "C"
|
} // end extern "C"
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,12 @@ class NormObjectSize
|
||||||
NormObjectSize(UINT16 msb, UINT32 lsb)
|
NormObjectSize(UINT16 msb, UINT32 lsb)
|
||||||
{
|
{
|
||||||
size = (Offset)lsb;
|
size = (Offset)lsb;
|
||||||
#if _FILE_OFFSET_BITS > 32
|
#if (_FILE_OFFSET_BITS > 32) && !defined(ANDROID)
|
||||||
size |= ((Offset)msb) << 32;
|
size |= ((Offset)msb) << 32;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Offset GetOffset() const {return size;}
|
Offset GetOffset() const {return size;}
|
||||||
#if _FILE_OFFSET_BITS > 32
|
#if (_FILE_OFFSET_BITS > 32) && !defined(ANDROID)
|
||||||
UINT16 MSB() const {return ((UINT16)((size >> 32) & 0x0000ffff));}
|
UINT16 MSB() const {return ((UINT16)((size >> 32) & 0x0000ffff));}
|
||||||
#else
|
#else
|
||||||
UINT16 MSB() const {return 0;}
|
UINT16 MSB() const {return 0;}
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,28 @@ class NormNode
|
||||||
friend class NormNodeListIterator;
|
friend class NormNodeListIterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NormNode(class NormSession& theSession, NormNodeId nodeId);
|
enum Type
|
||||||
|
{
|
||||||
|
ACKER,
|
||||||
|
SENDER,
|
||||||
|
CC_NODE
|
||||||
|
};
|
||||||
|
|
||||||
|
NormNode(Type theType, class NormSession& theSession, NormNodeId nodeId);
|
||||||
virtual ~NormNode();
|
virtual ~NormNode();
|
||||||
|
|
||||||
|
Type GetType() const
|
||||||
|
{return node_type;}
|
||||||
|
|
||||||
NormSession& GetSession() const {return session;}
|
NormSession& GetSession() const {return session;}
|
||||||
void Retain();
|
void Retain();
|
||||||
void Release();
|
void Release();
|
||||||
|
|
||||||
|
void SetUserData(const void* userData)
|
||||||
|
{user_data = userData;}
|
||||||
|
const void* GetUserData() const
|
||||||
|
{return user_data;}
|
||||||
|
|
||||||
const ProtoAddress& GetAddress() const {return addr;}
|
const ProtoAddress& GetAddress() const {return addr;}
|
||||||
void SetAddress(const ProtoAddress& address) {addr = address;}
|
void SetAddress(const ProtoAddress& address) {addr = address;}
|
||||||
const NormNodeId& GetId() const {return id;}
|
const NormNodeId& GetId() const {return id;}
|
||||||
|
|
@ -52,9 +67,11 @@ class NormNode
|
||||||
class NormSession& session;
|
class NormSession& session;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Type node_type;
|
||||||
NormNodeId id;
|
NormNodeId id;
|
||||||
ProtoAddress addr;
|
ProtoAddress addr;
|
||||||
unsigned int reference_count;
|
unsigned int reference_count;
|
||||||
|
const void* user_data;
|
||||||
// We keep NormNodes in a binary tree (TBD) make this a ProtoTree
|
// We keep NormNodes in a binary tree (TBD) make this a ProtoTree
|
||||||
NormNode* parent;
|
NormNode* parent;
|
||||||
NormNode* right;
|
NormNode* right;
|
||||||
|
|
@ -544,6 +561,7 @@ class NormSenderNode : public NormNode
|
||||||
|
|
||||||
// Watermark acknowledgement
|
// Watermark acknowledgement
|
||||||
ProtoTimer ack_timer;
|
ProtoTimer ack_timer;
|
||||||
|
bool ack_pending;
|
||||||
NormObjectId watermark_object_id;
|
NormObjectId watermark_object_id;
|
||||||
NormBlockId watermark_block_id;
|
NormBlockId watermark_block_id;
|
||||||
NormSegmentId watermark_segment_id;
|
NormSegmentId watermark_segment_id;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ class NormController
|
||||||
TX_RATE_CHANGED,
|
TX_RATE_CHANGED,
|
||||||
LOCAL_SENDER_CLOSED,
|
LOCAL_SENDER_CLOSED,
|
||||||
REMOTE_SENDER_NEW,
|
REMOTE_SENDER_NEW,
|
||||||
|
REMOTE_SENDER_RESET,
|
||||||
|
REMOTE_SENDER_ADDRESS,
|
||||||
REMOTE_SENDER_ACTIVE,
|
REMOTE_SENDER_ACTIVE,
|
||||||
REMOTE_SENDER_INACTIVE,
|
REMOTE_SENDER_INACTIVE,
|
||||||
REMOTE_SENDER_PURGED,
|
REMOTE_SENDER_PURGED,
|
||||||
|
|
@ -51,13 +53,16 @@ class NormController
|
||||||
RX_OBJECT_ABORTED,
|
RX_OBJECT_ABORTED,
|
||||||
GRTT_UPDATED,
|
GRTT_UPDATED,
|
||||||
CC_ACTIVE, // posted when cc feedback is detected
|
CC_ACTIVE, // posted when cc feedback is detected
|
||||||
CC_INACTIVE // posted when no cc feedback and min rate reached
|
CC_INACTIVE, // posted when no cc feedback and min rate reached
|
||||||
|
ACKING_NODE_NEW,
|
||||||
|
SEND_ERROR,
|
||||||
|
USER_TIMEOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void Notify(NormController::Event event,
|
virtual void Notify(NormController::Event event,
|
||||||
class NormSessionMgr* sessionMgr,
|
class NormSessionMgr* sessionMgr,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object) = 0;
|
class NormObject* object) = 0;
|
||||||
|
|
||||||
}; // end class NormController
|
}; // end class NormController
|
||||||
|
|
@ -81,11 +86,11 @@ class NormSessionMgr
|
||||||
|
|
||||||
void Notify(NormController::Event event,
|
void Notify(NormController::Event event,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object)
|
class NormObject* object)
|
||||||
{
|
{
|
||||||
if (controller)
|
if (controller)
|
||||||
controller->Notify(event, this, session, sender, object);
|
controller->Notify(event, this, session, node, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivateTimer(ProtoTimer& timer) {timer_mgr.ActivateTimer(timer);}
|
void ActivateTimer(ProtoTimer& timer) {timer_mgr.ActivateTimer(timer);}
|
||||||
|
|
@ -163,6 +168,7 @@ class NormSession
|
||||||
const ProtoAddress& Address() {return address;}
|
const ProtoAddress& Address() {return address;}
|
||||||
void SetAddress(const ProtoAddress& addr) {address = addr;}
|
void SetAddress(const ProtoAddress& addr) {address = addr;}
|
||||||
bool SetMulticastInterface(const char* interfaceName);
|
bool SetMulticastInterface(const char* interfaceName);
|
||||||
|
bool SetSSM(const char* sourceAddress);
|
||||||
bool SetTTL(UINT8 theTTL)
|
bool SetTTL(UINT8 theTTL)
|
||||||
{
|
{
|
||||||
bool result = tx_socket->IsOpen() ? tx_socket->SetTTL(theTTL) : true;
|
bool result = tx_socket->IsOpen() ? tx_socket->SetTTL(theTTL) : true;
|
||||||
|
|
@ -179,11 +185,18 @@ class NormSession
|
||||||
}
|
}
|
||||||
bool SetLoopback(bool state)
|
bool SetLoopback(bool state)
|
||||||
{
|
{
|
||||||
bool result = tx_socket->IsOpen() ? tx_socket->SetLoopback(state) : true;
|
bool result = state ? SetMulticastLoopback(true) : true;
|
||||||
loopback = result ? state : loopback;
|
loopback = result ? state : loopback;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SetMulticastLoopback(bool state)
|
||||||
|
{
|
||||||
|
bool result = tx_socket->IsOpen() ? tx_socket->SetLoopback(state) : true;
|
||||||
|
mcast_loopback = result ? state : mcast_loopback;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool SetFragmentation(bool state)
|
bool SetFragmentation(bool state)
|
||||||
{
|
{
|
||||||
bool result = tx_socket->IsOpen() ? tx_socket->SetFragmentation(state) : true;
|
bool result = tx_socket->IsOpen() ? tx_socket->SetFragmentation(state) : true;
|
||||||
|
|
@ -289,11 +302,11 @@ class NormSession
|
||||||
unsigned long countMin,
|
unsigned long countMin,
|
||||||
unsigned long countMax);
|
unsigned long countMax);
|
||||||
void Notify(NormController::Event event,
|
void Notify(NormController::Event event,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object)
|
class NormObject* object)
|
||||||
{
|
{
|
||||||
notify_pending = true;
|
notify_pending = true;
|
||||||
session_mgr.Notify(event, this, sender, object);
|
session_mgr.Notify(event, this, node, object);
|
||||||
notify_pending = false;
|
notify_pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,6 +321,8 @@ class NormSession
|
||||||
const void* GetUserData() const
|
const void* GetUserData() const
|
||||||
{return user_data;}
|
{return user_data;}
|
||||||
|
|
||||||
|
void SetUserTimer(double seconds); // set to value less than zero to cancel
|
||||||
|
|
||||||
// Sender methods
|
// Sender methods
|
||||||
void SenderSetBaseObjectId(NormObjectId baseId)
|
void SenderSetBaseObjectId(NormObjectId baseId)
|
||||||
{
|
{
|
||||||
|
|
@ -322,6 +337,8 @@ class NormSession
|
||||||
UINT16 numParity);
|
UINT16 numParity);
|
||||||
void StopSender();
|
void StopSender();
|
||||||
void SetTxOnly(bool txOnly, bool connectToSessionAddress = false);
|
void SetTxOnly(bool txOnly, bool connectToSessionAddress = false);
|
||||||
|
bool GetTxOnly() const
|
||||||
|
{return tx_only;}
|
||||||
|
|
||||||
NormStreamObject* QueueTxStream(UINT32 bufferSize,
|
NormStreamObject* QueueTxStream(UINT32 bufferSize,
|
||||||
bool doubleBuffer = false,
|
bool doubleBuffer = false,
|
||||||
|
|
@ -353,12 +370,17 @@ class NormSession
|
||||||
|
|
||||||
void SenderSetAutoAckingNodes(TrackingStatus trackingStatus)
|
void SenderSetAutoAckingNodes(TrackingStatus trackingStatus)
|
||||||
{acking_auto_populate = trackingStatus;}
|
{acking_auto_populate = trackingStatus;}
|
||||||
bool SenderAddAckingNode(NormNodeId nodeId);
|
NormAckingNode* SenderAddAckingNode(NormNodeId nodeId, const ProtoAddress* srcAddr = NULL);
|
||||||
void SenderRemoveAckingNode(NormNodeId nodeId);
|
void SenderRemoveAckingNode(NormNodeId nodeId);
|
||||||
AckingStatus SenderGetAckingStatus(NormNodeId nodeId);
|
AckingStatus SenderGetAckingStatus(NormNodeId nodeId);
|
||||||
// Set "prevNodeId = NORM_NODE_NONE" to init this iteration (returns "false" when done)
|
// Set "prevNodeId = NORM_NODE_NONE" to init this iteration (returns "false" when done)
|
||||||
bool SenderGetNextAckingNode(NormNodeId& prevNodeId, AckingStatus* ackingStatus = NULL);
|
bool SenderGetNextAckingNode(NormNodeId& prevNodeId, AckingStatus* ackingStatus = NULL);
|
||||||
|
|
||||||
|
NormAckingNode* SenderFindAckingNode(NormNodeId nodeId) const
|
||||||
|
{
|
||||||
|
return static_cast<NormAckingNode*>(acking_node_tree.FindNodeById(nodeId));
|
||||||
|
}
|
||||||
|
|
||||||
// App-defined command support methods
|
// App-defined command support methods
|
||||||
bool SenderSendCmd(const char* cmdBuffer, unsigned int cmdLength, bool robust);
|
bool SenderSendCmd(const char* cmdBuffer, unsigned int cmdLength, bool robust);
|
||||||
void SenderCancelCmd();
|
void SenderCancelCmd();
|
||||||
|
|
@ -557,6 +579,7 @@ class NormSession
|
||||||
bool OnReportTimeout(ProtoTimer& theTimer);
|
bool OnReportTimeout(ProtoTimer& theTimer);
|
||||||
bool OnCmdTimeout(ProtoTimer& theTimer);
|
bool OnCmdTimeout(ProtoTimer& theTimer);
|
||||||
bool OnFlowControlTimeout(ProtoTimer& theTimer);
|
bool OnFlowControlTimeout(ProtoTimer& theTimer);
|
||||||
|
bool OnUserTimeout(ProtoTimer& theTimer);
|
||||||
|
|
||||||
void TxSocketRecvHandler(ProtoSocket& theSocket, ProtoSocket::Event theEvent);
|
void TxSocketRecvHandler(ProtoSocket& theSocket, ProtoSocket::Event theEvent);
|
||||||
void RxSocketRecvHandler(ProtoSocket& theSocket, ProtoSocket::Event theEvent);
|
void RxSocketRecvHandler(ProtoSocket& theSocket, ProtoSocket::Event theEvent);
|
||||||
|
|
@ -624,12 +647,14 @@ class NormSession
|
||||||
|
|
||||||
// General session parameters
|
// General session parameters
|
||||||
NormNodeId local_node_id;
|
NormNodeId local_node_id;
|
||||||
ProtoAddress address; // session destination address/port
|
ProtoAddress address; // session destination address/port
|
||||||
UINT8 ttl; // session multicast ttl
|
ProtoAddress ssm_source_addr; // optional SSM source address
|
||||||
UINT8 tos; // session IPv4 TOS (or IPv6 traffic class - TBD)
|
UINT8 ttl; // session multicast ttl
|
||||||
bool loopback; // receive own traffic it true
|
UINT8 tos; // session IPv4 TOS (or IPv6 traffic class - TBD)
|
||||||
bool fragmentation; // enable UDP/IP fragmentation (i.e. clear DF bit) if true
|
bool loopback; // receive own traffic it true
|
||||||
bool ecn_enabled; // set true to get raw packets and check for ECN status
|
bool mcast_loopback; // enable socket multicast loopback if true
|
||||||
|
bool fragmentation; // enable UDP/IP fragmentation (i.e. clear DF bit) if true
|
||||||
|
bool ecn_enabled; // set true to get raw packets and check for ECN status
|
||||||
|
|
||||||
char interface_name[IFACE_NAME_MAX+1];
|
char interface_name[IFACE_NAME_MAX+1];
|
||||||
double tx_rate; // bytes per second
|
double tx_rate; // bytes per second
|
||||||
|
|
@ -763,6 +788,7 @@ class NormSession
|
||||||
double rx_loss_rate; // for uncorrelated loss
|
double rx_loss_rate; // for uncorrelated loss
|
||||||
double report_timer_interval;
|
double report_timer_interval;
|
||||||
|
|
||||||
|
ProtoTimer user_timer;
|
||||||
const void* user_data;
|
const void* user_data;
|
||||||
|
|
||||||
// Linkers
|
// Linkers
|
||||||
|
|
@ -774,6 +800,7 @@ void NormTrace(const struct timeval& currentTime,
|
||||||
NormNodeId localId,
|
NormNodeId localId,
|
||||||
const NormMsg& msg,
|
const NormMsg& msg,
|
||||||
bool sent,
|
bool sent,
|
||||||
UINT8 fecM);
|
UINT8 fecM,
|
||||||
|
UINT16 instId = 0); // this might not always be available to caller
|
||||||
|
|
||||||
#endif // _NORM_SESSION
|
#endif // _NORM_SESSION
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,6 @@
|
||||||
|
|
||||||
#ifndef _NORM_VERSION
|
#ifndef _NORM_VERSION
|
||||||
#define _NORM_VERSION
|
#define _NORM_VERSION
|
||||||
#define VERSION "1.5b4"
|
#define VERSION "1.5r5"
|
||||||
#endif // _NORM_VERSION
|
#endif // _NORM_VERSION
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ NS = ../src/sim/ns
|
||||||
INCLUDES = $(SYSTEM_INCLUDES) -I$(UNIX) -I../include -I$(PROTOLIB)/include
|
INCLUDES = $(SYSTEM_INCLUDES) -I$(UNIX) -I../include -I$(PROTOLIB)/include
|
||||||
|
|
||||||
CFLAGS = -g -DPROTO_DEBUG -DUNIX -D_FILE_OFFSET_BITS=64 -O $(SYSTEM_CFLAGS) $(SYSTEM_HAVES) $(INCLUDES)
|
CFLAGS = -g -DPROTO_DEBUG -DUNIX -D_FILE_OFFSET_BITS=64 -O $(SYSTEM_CFLAGS) $(SYSTEM_HAVES) $(INCLUDES)
|
||||||
|
#CFLAGS = -g -DPROTO_DEBUG -DUNIX -D_FILE_OFFSET_BITS=64 $(SYSTEM_CFLAGS) $(SYSTEM_HAVES) $(INCLUDES)
|
||||||
|
|
||||||
LDFLAGS = $(SYSTEM_LDFLAGS)
|
LDFLAGS = $(SYSTEM_LDFLAGS)
|
||||||
|
|
||||||
|
|
@ -239,7 +240,7 @@ gtf: $(GTF_OBJ)
|
||||||
cp $@ ../bin/$@
|
cp $@ ../bin/$@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(COMMON)/*.o $(UNIX)/*.o $(NS)/*.o \
|
rm -f $(COMMON)/*.o $(UNIX)/*.o $(NS)/*.o $(EXAMPLE)/*.o \
|
||||||
libnorm.a libnorm.$(SYSTEM_SOEXT) ../lib/libnorm.a ../lib/libnorm.$(SYSTEM_SOEXT) \
|
libnorm.a libnorm.$(SYSTEM_SOEXT) ../lib/libnorm.a ../lib/libnorm.$(SYSTEM_SOEXT) \
|
||||||
norm raft normTest normTest2 normThreadTest normThreadTest2 ../bin/*;
|
norm raft normTest normTest2 normThreadTest normThreadTest2 ../bin/*;
|
||||||
$(MAKE) -C $(PROTOLIB)/makefiles -f Makefile.$(SYSTEM) clean
|
$(MAKE) -C $(PROTOLIB)/makefiles -f Makefile.$(SYSTEM) clean
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,10 @@ SYSTEM_HAVES = -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_GETLOGIN -DHAVE_FLOCK -DHAVE_DI
|
||||||
SYSTEM_SRC =
|
SYSTEM_SRC =
|
||||||
|
|
||||||
SYSTEM = freebsd
|
SYSTEM = freebsd
|
||||||
CC = g++
|
CC = c++
|
||||||
SYSTEM_CFLAGS = -fPIC -Wall -pedantic -Wcast-align
|
SYSTEM_CFLAGS = -fPIC -Wall -pedantic -Wcast-align
|
||||||
SYSTEM_SOFLAGS = -shared
|
SYSTEM_SOFLAGS = -shared
|
||||||
|
SYSTEM_SOEXT = so
|
||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
AR = ar
|
AR = ar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ SYSTEM_LIBS = -lresolv -lpcap
|
||||||
#
|
#
|
||||||
|
|
||||||
SYSTEM_HAVES = -DMACOSX -DECN_SUPPORT -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_GETLOGIN -DHAVE_FLOCK \
|
SYSTEM_HAVES = -DMACOSX -DECN_SUPPORT -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_GETLOGIN -DHAVE_FLOCK \
|
||||||
-D_FILE_OFFSET_BITS=64 -DHAVE_DIRFD
|
-D_FILE_OFFSET_BITS=64 -DHAVE_DIRFD -DUSE_SELECT
|
||||||
|
|
||||||
SYSTEM_SRC = ../protolib/src/unix/bpfCap.cpp
|
SYSTEM_SRC = ../protolib/src/unix/bpfCap.cpp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormLib", "NormLib.vcproj", "{D7B0023C-8798-4918-8DA0-05C9054D70B9}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "norm", "norm\norm.vcproj", "{6E1308A6-D40F-489E-A4F1-40D859380D64}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9} = {D7B0023C-8798-4918-8DA0-05C9054D70B9}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "normTest", "normTest.vcproj", "{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
||||||
|
{182006F3-188F-466E-89FE-8421C0478691} = {182006F3-188F-466E-89FE-8421C0478691}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormDll", "NormDll.vcproj", "{182006F3-188F-466E-89FE-8421C0478691}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npc", "npc.vcproj", "{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9} = {D7B0023C-8798-4918-8DA0-05C9054D70B9}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Protokit", "..\..\protolib\makefiles\win32\Protokit.vcproj", "{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{D7B0023C-8798-4918-8DA0-05C9054D70B9}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{6E1308A6-D40F-489E-A4F1-40D859380D64}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{6E1308A6-D40F-489E-A4F1-40D859380D64}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{6E1308A6-D40F-489E-A4F1-40D859380D64}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{6E1308A6-D40F-489E-A4F1-40D859380D64}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{182006F3-188F-466E-89FE-8421C0478691}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{182006F3-188F-466E-89FE-8421C0478691}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{182006F3-188F-466E-89FE-8421C0478691}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{182006F3-188F-466E-89FE-8421C0478691}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -1,32 +1,18 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2008
|
# Visual Studio Express 2013 for Windows Desktop
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormLib", "NormLib.vcproj", "{D7B0023C-8798-4918-8DA0-05C9054D70B9}"
|
VisualStudioVersion = 12.0.30723.0
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormLib", "NormLib.vcxproj", "{D7B0023C-8798-4918-8DA0-05C9054D70B9}"
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "norm", "norm\norm.vcproj", "{6E1308A6-D40F-489E-A4F1-40D859380D64}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "norm", "norm\norm.vcxproj", "{6E1308A6-D40F-489E-A4F1-40D859380D64}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{D7B0023C-8798-4918-8DA0-05C9054D70B9} = {D7B0023C-8798-4918-8DA0-05C9054D70B9}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "normTest", "normTest.vcproj", "{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "normTest", "normTest.vcxproj", "{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
|
||||||
{182006F3-188F-466E-89FE-8421C0478691} = {182006F3-188F-466E-89FE-8421C0478691}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormDll", "NormDll.vcproj", "{182006F3-188F-466E-89FE-8421C0478691}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NormDll", "NormDll.vcxproj", "{182006F3-188F-466E-89FE-8421C0478691}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9} = {DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npc", "npc.vcproj", "{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npc", "npc.vcxproj", "{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{D7B0023C-8798-4918-8DA0-05C9054D70B9} = {D7B0023C-8798-4918-8DA0-05C9054D70B9}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Protokit", "..\..\protolib\makefiles\win32\Protokit.vcproj", "{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Protokit", "..\..\protolib\makefiles\win32\Protokit.vcxproj", "{DE94F096-A09B-44B6-8EFE-C7BF1F65C4C9}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{182006F3-188F-466E-89FE-8421C0478691}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>Debug\</OutDir>
|
||||||
|
<IntDir>Debug\</IntDir>
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>Release\</OutDir>
|
||||||
|
<IntDir>Release\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NORM_USE_DLL;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)Norm.dll</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<ProgramDatabaseFile>$(OutDir)NormDll.pdb</ProgramDatabaseFile>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<ImportLibrary>$(OutDir)Norm.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NORM_USE_DLL;NDEBUG;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)Norm.dll</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<ImportLibrary>$(OutDir)Norm.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\common\galois.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normApi.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoder.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderMDP.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderRS16.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderRS8.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normFile.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normMessage.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normNode.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normObject.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normSegment.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normSession.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="ReadMe.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\protolib\makefiles\win32\Protokit.vcxproj">
|
||||||
|
<Project>{de94f096-a09b-44b6-8efe-c7bf1f65c4c9}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{D7B0023C-8798-4918-8DA0-05C9054D70B9}</ProjectGuid>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>.\Debug\</OutDir>
|
||||||
|
<IntDir>.\Debug\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>.\Release\</OutDir>
|
||||||
|
<IntDir>.\Release\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Debug/NormLib.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Lib>
|
||||||
|
<OutputFile>.\Debug\NormLib.lib</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
</Lib>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Release/NormLib.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Release/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Lib>
|
||||||
|
<OutputFile>.\Release\NormLib.lib</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
</Lib>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\common\galois.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normApi.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoder.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderMDP.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderRS16.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normEncoderRS8.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normFile.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normMessage.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normNode.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normObject.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normSegment.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\common\normSession.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
Visual Studio 2012 and 2013 require different versions of the Platform Toolset:
|
||||||
|
|
||||||
|
Visual Studio 2012 v110 (or v110_xp for applications that need to run
|
||||||
|
under Windows XP)
|
||||||
|
|
||||||
|
Visual Studio 2013 v120 (or v120_xp for applications that need to run
|
||||||
|
under Windows XP)
|
||||||
|
|
||||||
|
For each project included by the solution file modify the Platform
|
||||||
|
Toolset under project Configuration Properties, General as appropriate
|
||||||
|
for your Visual Studio version.
|
||||||
|
|
||||||
|
A Visual Studio solutions file and associated .vcproj files are
|
||||||
|
included as a convenience for those using earlier versions of visual
|
||||||
|
studio (2008 and 2010): Norm-2008.sln
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{6E1308A6-D40F-489E-A4F1-40D859380D64}</ProjectGuid>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>.\Debug\</OutDir>
|
||||||
|
<IntDir>.\Debug\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>.\Release\</OutDir>
|
||||||
|
<IntDir>.\Release\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<TargetEnvironment>Win32</TargetEnvironment>
|
||||||
|
<TypeLibraryName>.\Debug/norm.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/vmg %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\include;..\..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_CRT_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Debug/norm.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>.\Debug/norm.exe</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<ProgramDatabaseFile>.\Debug/norm.pdb</ProgramDatabaseFile>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<TargetEnvironment>Win32</TargetEnvironment>
|
||||||
|
<TypeLibraryName>.\Release/norm.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/vmg %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\include;..\..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Release/norm.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Release/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||||
|
<BrowseInformation>true</BrowseInformation>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>.\Release/norm.exe</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<ProgramDatabaseFile>.\Release/norm.pdb</ProgramDatabaseFile>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\common\normApp.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\common\normPostProcess.cpp" />
|
||||||
|
<ClCompile Include="..\win32PostProcess.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\protolib\makefiles\win32\Protokit.vcxproj">
|
||||||
|
<Project>{de94f096-a09b-44b6-8efe-c7bf1f65c4c9}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\NormLib.vcxproj">
|
||||||
|
<Project>{d7b0023c-8798-4918-8da0-05c9054d70b9}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{32CF83E0-D2E0-4E43-8F7B-72BD0AB64647}</ProjectGuid>
|
||||||
|
<RootNamespace>normTest</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>.\Debug\</OutDir>
|
||||||
|
<IntDir>.\Debug\</IntDir>
|
||||||
|
<LinkIncremental />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>.\Release\</OutDir>
|
||||||
|
<IntDir>.\Release\</IntDir>
|
||||||
|
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<TypeLibraryName>.\Debug/normTest.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NORM_USE_DLL;PROTO_DEBUG;HAVE_ASSERT;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Debug/normTest.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>.\Debug/normTest.exe</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<AdditionalLibraryDirectories>./;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<ProgramDatabaseFile>.\Debug/normTest.pdb</ProgramDatabaseFile>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<TypeLibraryName>.\Release/normTest.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NORM_USE_DLL;PROTO_DEBUG;WIN32;HAVE_ASSERT;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Release/normTest.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Release/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>.\Release/normTest.exe</OutputFile>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<ProgramDatabaseFile>.\Release/normTest.pdb</ProgramDatabaseFile>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\common\normTest.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\protolib\makefiles\win32\Protokit.vcxproj">
|
||||||
|
<Project>{de94f096-a09b-44b6-8efe-c7bf1f65c4c9}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="NormDll.vcxproj">
|
||||||
|
<Project>{182006f3-188f-466e-89fe-8421c0478691}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{7BF4525B-9185-4296-A2BF-FFE77BB66EAF}</ProjectGuid>
|
||||||
|
<RootNamespace>normTest</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<UseOfMfc>false</UseOfMfc>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>.\Debug\</OutDir>
|
||||||
|
<IntDir>.\Debug\</IntDir>
|
||||||
|
<LinkIncremental />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>.\Release\</OutDir>
|
||||||
|
<IntDir>.\Release\</IntDir>
|
||||||
|
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<TypeLibraryName>.\Debug/normTest.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Debug/normTest.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<AdditionalLibraryDirectories>./;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Midl>
|
||||||
|
<TypeLibraryName>.\Release/normTest.tlb</TypeLibraryName>
|
||||||
|
<HeaderFileName />
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include;..\..\protolib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;PROTO_DEBUG;HAVE_IPV6;HAVE_ASSERT;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<PrecompiledHeaderOutputFile>.\Release/normTest.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>.\Release/</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<Culture>0x0409</Culture>
|
||||||
|
</ResourceCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>iphlpapi.lib;ws2_32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention />
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\common\normPrecode.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="NormLib.vcxproj">
|
||||||
|
<Project>{d7b0023c-8798-4918-8da0-05c9054d70b9}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -40,7 +40,7 @@ class NormInstance : public NormController
|
||||||
void Notify(NormController::Event event,
|
void Notify(NormController::Event event,
|
||||||
class NormSessionMgr* sessionMgr,
|
class NormSessionMgr* sessionMgr,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object);
|
class NormObject* object);
|
||||||
|
|
||||||
bool Startup(bool priorityBoost = false);
|
bool Startup(bool priorityBoost = false);
|
||||||
|
|
@ -68,10 +68,13 @@ class NormInstance : public NormController
|
||||||
bool GetNextEvent(NormEvent* theEvent);
|
bool GetNextEvent(NormEvent* theEvent);
|
||||||
bool SetCacheDirectory(const char* cachePath);
|
bool SetCacheDirectory(const char* cachePath);
|
||||||
|
|
||||||
|
void ReleasePreviousEvent();
|
||||||
|
|
||||||
bool NotifyQueueIsEmpty() const
|
bool NotifyQueueIsEmpty() const
|
||||||
{return notify_queue.IsEmpty();}
|
{return notify_queue.IsEmpty();}
|
||||||
|
|
||||||
void PurgeSessionNotifications(NormSessionHandle sessionHandle);
|
void PurgeSessionNotifications(NormSessionHandle sessionHandle);
|
||||||
|
void PurgeNodeNotifications(NormNodeHandle nodeHandle);
|
||||||
void PurgeObjectNotifications(NormObjectHandle objectHandle);
|
void PurgeObjectNotifications(NormObjectHandle objectHandle);
|
||||||
void PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType);
|
void PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType);
|
||||||
|
|
||||||
|
|
@ -96,7 +99,7 @@ class NormInstance : public NormController
|
||||||
static NormInstance* GetInstanceFromNode(NormNodeHandle nodeHandle)
|
static NormInstance* GetInstanceFromNode(NormNodeHandle nodeHandle)
|
||||||
{
|
{
|
||||||
if (NORM_NODE_INVALID == nodeHandle) return ((NormInstance*)NULL);
|
if (NORM_NODE_INVALID == nodeHandle) return ((NormInstance*)NULL);
|
||||||
NormSession& session = ((NormSenderNode*)nodeHandle)->GetSession();
|
NormSession& session = ((NormNode*)nodeHandle)->GetSession();
|
||||||
return static_cast<NormInstance*>(session.GetSessionMgr().GetController());
|
return static_cast<NormInstance*>(session.GetSessionMgr().GetController());
|
||||||
}
|
}
|
||||||
static NormInstance* GetInstanceFromObject(NormObjectHandle objectHandle)
|
static NormInstance* GetInstanceFromObject(NormObjectHandle objectHandle)
|
||||||
|
|
@ -158,6 +161,17 @@ class NormInstance : public NormController
|
||||||
NormSessionMgr session_mgr;
|
NormSessionMgr session_mgr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ResetNotificationEvent()
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
if (0 == ResetEvent(notify_event))
|
||||||
|
PLOG(PL_ERROR, "NormInstance::GetNextEvent() ResetEvent error: %s\n", GetErrorString());
|
||||||
|
#else
|
||||||
|
char byte[32];
|
||||||
|
while (read(notify_fd[0], byte, 32) > 0); // TBD - error check
|
||||||
|
#endif // if/else WIN32/UNIX
|
||||||
|
}
|
||||||
|
|
||||||
Notification::Queue notify_pool;
|
Notification::Queue notify_pool;
|
||||||
Notification::Queue notify_queue;
|
Notification::Queue notify_queue;
|
||||||
Notification* previous_notification;
|
Notification* previous_notification;
|
||||||
|
|
@ -248,7 +262,7 @@ bool NormInstance::SetCacheDirectory(const char* cachePath)
|
||||||
void NormInstance::Notify(NormController::Event event,
|
void NormInstance::Notify(NormController::Event event,
|
||||||
class NormSessionMgr* sessionMgr,
|
class NormSessionMgr* sessionMgr,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object)
|
class NormObject* object)
|
||||||
{
|
{
|
||||||
// (TBD) set a limit on how many pending notifications
|
// (TBD) set a limit on how many pending notifications
|
||||||
|
|
@ -389,13 +403,13 @@ void NormInstance::Notify(NormController::Event event,
|
||||||
// "Retain" any valid "object" or "sender" handles for API access
|
// "Retain" any valid "object" or "sender" handles for API access
|
||||||
if (NORM_OBJECT_INVALID != object)
|
if (NORM_OBJECT_INVALID != object)
|
||||||
((NormObject*)object)->Retain();
|
((NormObject*)object)->Retain();
|
||||||
else if (NORM_NODE_INVALID != sender)
|
else if (NORM_NODE_INVALID != node)
|
||||||
((NormSenderNode*)sender)->Retain();
|
((NormNode*)node)->Retain();
|
||||||
|
|
||||||
bool doNotify = notify_queue.IsEmpty();
|
bool doNotify = notify_queue.IsEmpty();
|
||||||
n->event.type = (NormEventType)event;
|
n->event.type = (NormEventType)event;
|
||||||
n->event.session = session;
|
n->event.session = session;
|
||||||
n->event.sender = sender;
|
n->event.sender = node;
|
||||||
n->event.object = object;
|
n->event.object = object;
|
||||||
notify_queue.Append(n);
|
notify_queue.Append(n);
|
||||||
|
|
||||||
|
|
@ -422,6 +436,7 @@ void NormInstance::Notify(NormController::Event event,
|
||||||
}
|
}
|
||||||
} // end NormInstance::Notify()
|
} // end NormInstance::Notify()
|
||||||
|
|
||||||
|
// Purge any notifications associated with a specific object
|
||||||
void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle)
|
void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle)
|
||||||
{
|
{
|
||||||
if (NORM_OBJECT_INVALID == objectHandle) return;
|
if (NORM_OBJECT_INVALID == objectHandle) return;
|
||||||
|
|
@ -449,17 +464,28 @@ void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle)
|
||||||
next = next->GetNext();
|
next = next->GetNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((NULL != previous_notification) && (objectHandle == previous_notification->event.object))
|
||||||
|
{
|
||||||
|
// "Release" any previously-retained object or node handle
|
||||||
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
|
notify_pool.Append(previous_notification);
|
||||||
|
previous_notification = NULL;
|
||||||
|
}
|
||||||
// TBD - check if event queue is emptied and reset event/fd
|
// TBD - check if event queue is emptied and reset event/fd
|
||||||
} // end NormInstance::PurgeObjectNotifications()
|
} // end NormInstance::PurgeObjectNotifications()
|
||||||
|
|
||||||
void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
|
// Purge any notifications associated with a specific object
|
||||||
|
void NormInstance::PurgeNodeNotifications(NormNodeHandle nodeHandle)
|
||||||
{
|
{
|
||||||
|
if (NORM_NODE_INVALID == nodeHandle) return;
|
||||||
Notification* prev = NULL;
|
Notification* prev = NULL;
|
||||||
Notification* next = notify_queue.GetHead();
|
Notification* next = notify_queue.GetHead();
|
||||||
while (NULL != next)
|
while (next)
|
||||||
{
|
{
|
||||||
if (next->event.session == sessionHandle)
|
if (nodeHandle == next->event.sender)
|
||||||
{
|
{
|
||||||
|
// "Release" the previously-retained object handle
|
||||||
|
((NormNode*)nodeHandle)->Release();
|
||||||
// Remove this notification from queue and return to pool
|
// Remove this notification from queue and return to pool
|
||||||
Notification* current = next;
|
Notification* current = next;
|
||||||
next = next->GetNext();
|
next = next->GetNext();
|
||||||
|
|
@ -476,11 +502,65 @@ void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
|
||||||
next = next->GetNext();
|
next = next->GetNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TBD - check if event queue is emptied and reset event/fd
|
if ((NULL != previous_notification) && (nodeHandle == previous_notification->event.sender))
|
||||||
|
{
|
||||||
|
// "Release" any previously-retained object or node handle
|
||||||
|
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
||||||
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
|
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
||||||
|
((NormNode*)(previous_notification->event.sender))->Release();
|
||||||
|
notify_pool.Append(previous_notification);
|
||||||
|
previous_notification = NULL;
|
||||||
|
}
|
||||||
|
if (notify_queue.IsEmpty()) ResetNotificationEvent();
|
||||||
|
} // end NormInstance::PurgeNodeNotifications()
|
||||||
|
|
||||||
|
void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
|
||||||
|
{
|
||||||
|
if (NORM_SESSION_INVALID == sessionHandle) return;
|
||||||
|
Notification* prev = NULL;
|
||||||
|
Notification* next = notify_queue.GetHead();
|
||||||
|
while (NULL != next)
|
||||||
|
{
|
||||||
|
if (next->event.session == sessionHandle)
|
||||||
|
{
|
||||||
|
// Remove this notification from queue and return to pool
|
||||||
|
Notification* current = next;
|
||||||
|
next = next->GetNext();
|
||||||
|
if (NULL != prev)
|
||||||
|
prev->Append(next);
|
||||||
|
else
|
||||||
|
notify_queue.RemoveHead();
|
||||||
|
if (NULL == next) notify_queue.SetTail(prev);
|
||||||
|
if (NORM_OBJECT_INVALID != current->event.object)
|
||||||
|
((NormObject*)current->event.object)->Release();
|
||||||
|
else if (NORM_NODE_INVALID != current->event.sender)
|
||||||
|
((NormNode*)current->event.sender)->Release();
|
||||||
|
notify_pool.Append(current);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev = next;
|
||||||
|
next = next->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((NULL != previous_notification) && (sessionHandle == previous_notification->event.session))
|
||||||
|
{
|
||||||
|
// "Release" any previously-retained object or node handle
|
||||||
|
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
||||||
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
|
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
||||||
|
((NormNode*)(previous_notification->event.sender))->Release();
|
||||||
|
notify_pool.Append(previous_notification);
|
||||||
|
previous_notification = NULL;
|
||||||
|
}
|
||||||
|
if (notify_queue.IsEmpty()) ResetNotificationEvent();
|
||||||
} // end NormInstance::PurgeSessionNotifications()
|
} // end NormInstance::PurgeSessionNotifications()
|
||||||
|
|
||||||
|
// Purges notifications of a specific type for a specific session
|
||||||
void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType)
|
void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType)
|
||||||
{
|
{
|
||||||
|
if (NORM_SESSION_INVALID == sessionHandle) return;
|
||||||
Notification* prev = NULL;
|
Notification* prev = NULL;
|
||||||
Notification* next = notify_queue.GetHead();
|
Notification* next = notify_queue.GetHead();
|
||||||
while (next)
|
while (next)
|
||||||
|
|
@ -496,6 +576,10 @@ void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEvent
|
||||||
else
|
else
|
||||||
notify_queue.RemoveHead();
|
notify_queue.RemoveHead();
|
||||||
if (NULL == next) notify_queue.SetTail(prev);
|
if (NULL == next) notify_queue.SetTail(prev);
|
||||||
|
if (NORM_OBJECT_INVALID != current->event.object)
|
||||||
|
((NormObject*)current->event.object)->Release();
|
||||||
|
else if (NORM_NODE_INVALID != current->event.sender)
|
||||||
|
((NormNode*)current->event.sender)->Release();
|
||||||
notify_pool.Append(current);
|
notify_pool.Append(current);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -504,7 +588,7 @@ void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEvent
|
||||||
next = next->GetNext();
|
next = next->GetNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TBD - check if event queue is emptied and reset event/fd
|
if (notify_queue.IsEmpty()) ResetNotificationEvent();
|
||||||
} // end NormInstance::PurgeNotifications()
|
} // end NormInstance::PurgeNotifications()
|
||||||
|
|
||||||
// NormInstance::dispatcher MUST be suspended _before_ calling this
|
// NormInstance::dispatcher MUST be suspended _before_ calling this
|
||||||
|
|
@ -517,7 +601,7 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
|
||||||
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
||||||
((NormObject*)(previous_notification->event.object))->Release();
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
||||||
((NormSenderNode*)(previous_notification->event.sender))->Release();
|
((NormNode*)(previous_notification->event.sender))->Release();
|
||||||
notify_pool.Append(previous_notification);
|
notify_pool.Append(previous_notification);
|
||||||
previous_notification = NULL;
|
previous_notification = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -556,23 +640,17 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
|
||||||
else if (NULL != theEvent)
|
else if (NULL != theEvent)
|
||||||
{
|
{
|
||||||
theEvent->type = NORM_EVENT_INVALID;
|
theEvent->type = NORM_EVENT_INVALID;
|
||||||
theEvent->session = NORM_SESSION_INVALID;
|
theEvent->session = NORM_SESSION_INVALID;
|
||||||
theEvent->sender = NORM_SESSION_INVALID;
|
theEvent->sender = NORM_NODE_INVALID;
|
||||||
theEvent->object = NORM_SESSION_INVALID;
|
theEvent->object = NORM_OBJECT_INVALID;
|
||||||
}
|
}
|
||||||
if (notify_queue.IsEmpty())
|
if (notify_queue.IsEmpty())
|
||||||
{
|
ResetNotificationEvent();
|
||||||
#ifdef WIN32
|
|
||||||
if (0 == ResetEvent(notify_event))
|
|
||||||
PLOG(PL_ERROR, "NormInstance::GetNextEvent() ResetEvent error: %s\n", GetErrorString());
|
|
||||||
#else
|
|
||||||
char byte[32];
|
|
||||||
while (read(notify_fd[0], byte, 32) > 0); // TBD - error check
|
|
||||||
#endif // if/else WIN32/UNIX
|
|
||||||
}
|
|
||||||
return (NULL != n);
|
return (NULL != n);
|
||||||
} // end NormInstance::GetNextEvent()
|
} // end NormInstance::GetNextEvent()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool NormInstance::WaitForEvent()
|
bool NormInstance::WaitForEvent()
|
||||||
{
|
{
|
||||||
if (!dispatcher.IsThreaded())
|
if (!dispatcher.IsThreaded())
|
||||||
|
|
@ -640,6 +718,35 @@ bool NormInstance::Startup(bool priorityBoost)
|
||||||
return dispatcher.StartThread(priorityBoost);
|
return dispatcher.StartThread(priorityBoost);
|
||||||
} // end NormInstance::Startup()
|
} // end NormInstance::Startup()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void NormInstance::ReleasePreviousEvent()
|
||||||
|
{
|
||||||
|
// Garbage collect our "previous_notification"
|
||||||
|
if (NULL != previous_notification)
|
||||||
|
{
|
||||||
|
// Release any previously-retained object or node handles
|
||||||
|
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
||||||
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
|
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
||||||
|
((NormNode*)(previous_notification->event.sender))->Release();
|
||||||
|
notify_pool.Append(previous_notification);
|
||||||
|
previous_notification = NULL;
|
||||||
|
}
|
||||||
|
} // end NormInstance::ReleasePreviousEvent()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormReleasePreviousEvent(NormInstanceHandle instanceHandle)
|
||||||
|
{
|
||||||
|
NormInstance* instance = (NormInstance*)instanceHandle;
|
||||||
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
|
{
|
||||||
|
instance->ReleasePreviousEvent();
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
|
}
|
||||||
|
} // end NormReleasePreviousEvent()
|
||||||
|
|
||||||
|
|
||||||
void NormInstance::Shutdown()
|
void NormInstance::Shutdown()
|
||||||
{
|
{
|
||||||
dispatcher.Stop();
|
dispatcher.Stop();
|
||||||
|
|
@ -670,7 +777,7 @@ void NormInstance::Shutdown()
|
||||||
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
if (NORM_OBJECT_INVALID != previous_notification->event.object)
|
||||||
((NormObject*)(previous_notification->event.object))->Release();
|
((NormObject*)(previous_notification->event.object))->Release();
|
||||||
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
else if (NORM_NODE_INVALID != previous_notification->event.sender)
|
||||||
((NormSenderNode*)(previous_notification->event.sender))->Release();
|
((NormNode*)(previous_notification->event.sender))->Release();
|
||||||
notify_pool.Append(previous_notification);
|
notify_pool.Append(previous_notification);
|
||||||
previous_notification = NULL;
|
previous_notification = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -699,7 +806,7 @@ void NormInstance::Shutdown()
|
||||||
if (NORM_OBJECT_INVALID != n->event.object)
|
if (NORM_OBJECT_INVALID != n->event.object)
|
||||||
((NormObject*)(n->event.object))->Release();
|
((NormObject*)(n->event.object))->Release();
|
||||||
else if (NORM_NODE_INVALID != n->event.sender)
|
else if (NORM_NODE_INVALID != n->event.sender)
|
||||||
((NormSenderNode*)(n->event.sender))->Release();
|
((NormNode*)(n->event.sender))->Release();
|
||||||
delete n;
|
delete n;
|
||||||
}
|
}
|
||||||
notify_pool.Destroy();
|
notify_pool.Destroy();
|
||||||
|
|
@ -838,8 +945,8 @@ bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent, bo
|
||||||
if (!instance->WaitForEvent())
|
if (!instance->WaitForEvent())
|
||||||
{
|
{
|
||||||
// Indication that NormInstance is dead
|
// Indication that NormInstance is dead
|
||||||
// TBD - how do we inform app although this shouldn't
|
// TBD - how do we inform app although this shouldn't
|
||||||
// happen unless the app destroys the "instance"
|
// happen unless the app destroys the "instance"
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// re-suspend thread after wait
|
// re-suspend thread after wait
|
||||||
|
|
@ -857,6 +964,7 @@ bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent, bo
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormIsUnicastAddress(const char* address)
|
bool NormIsUnicastAddress(const char* address)
|
||||||
{
|
{
|
||||||
|
// TBD - is this really a thread-safe thing to do?
|
||||||
ProtoAddress addr;
|
ProtoAddress addr;
|
||||||
if ((NULL != address) && addr.ResolveFromString(address))
|
if ((NULL != address) && addr.ResolveFromString(address))
|
||||||
return addr.IsUnicast();
|
return addr.IsUnicast();
|
||||||
|
|
@ -873,11 +981,13 @@ NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
|
||||||
{
|
{
|
||||||
// (TBD) wrap this with SuspendThread/ResumeThread ???
|
// (TBD) wrap this with SuspendThread/ResumeThread ???
|
||||||
NormInstance* instance = (NormInstance*)instanceHandle;
|
NormInstance* instance = (NormInstance*)instanceHandle;
|
||||||
if (instance)
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSession* session =
|
NormSession* session =
|
||||||
instance->session_mgr.NewSession(sessionAddr, sessionPort, localNodeId);
|
instance->session_mgr.NewSession(sessionAddr, sessionPort, localNodeId);
|
||||||
if (session) return ((NormSessionHandle)session);
|
instance->dispatcher.ResumeThread();
|
||||||
|
if (session)
|
||||||
|
return ((NormSessionHandle)session);
|
||||||
}
|
}
|
||||||
return NORM_SESSION_INVALID;
|
return NORM_SESSION_INVALID;
|
||||||
} // end NormCreateSession()
|
} // end NormCreateSession()
|
||||||
|
|
@ -886,34 +996,35 @@ NORM_API_LINKAGE
|
||||||
void NormDestroySession(NormSessionHandle sessionHandle)
|
void NormDestroySession(NormSessionHandle sessionHandle)
|
||||||
{
|
{
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
if (instance)
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
if (instance->dispatcher.SuspendThread())
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (NULL != session)
|
||||||
{
|
{
|
||||||
NormSession* session = (NormSession*)sessionHandle;
|
session->Close();
|
||||||
if (NULL != session)
|
session->GetSessionMgr().DeleteSession(session);
|
||||||
{
|
instance->PurgeSessionNotifications(sessionHandle);
|
||||||
session->Close();
|
|
||||||
session->GetSessionMgr().DeleteSession(session);
|
|
||||||
instance->PurgeSessionNotifications(sessionHandle);
|
|
||||||
}
|
|
||||||
instance->dispatcher.ResumeThread();
|
|
||||||
}
|
}
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
} // end NormDestroySession()
|
} // end NormDestroySession()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
NormInstanceHandle NormGetInstance(NormSessionHandle sessionHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (NormInstanceHandle)NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
|
} // end NormGetIntance()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormSetUserData(NormSessionHandle sessionHandle, const void* userData)
|
void NormSetUserData(NormSessionHandle sessionHandle, const void* userData)
|
||||||
{
|
{
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
if (instance)
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
if (instance->dispatcher.SuspendThread())
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
{
|
if (session) session->SetUserData(userData);
|
||||||
NormSession* session = (NormSession*)sessionHandle;
|
instance->dispatcher.ResumeThread();
|
||||||
if (session) session->SetUserData(userData);
|
|
||||||
instance->dispatcher.ResumeThread();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // end NormSetUserData()
|
} // end NormSetUserData()
|
||||||
|
|
||||||
|
|
@ -935,6 +1046,40 @@ const void* NormGetUserData(NormSessionHandle sessionHandle)
|
||||||
return userData;
|
return userData;
|
||||||
} // end NormGetUserData()
|
} // end NormGetUserData()
|
||||||
|
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormSetUserTimer(NormSessionHandle sessionHandle, double seconds)
|
||||||
|
{
|
||||||
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
|
if (instance)
|
||||||
|
{
|
||||||
|
if (instance->dispatcher.SuspendThread())
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (session) session->SetUserTimer(seconds);
|
||||||
|
instance->PurgeNotifications(sessionHandle, NORM_USER_TIMEOUT);
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end NormSetUserTimer()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormCancelUserTimer(NormSessionHandle sessionHandle)
|
||||||
|
{
|
||||||
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
|
if (instance)
|
||||||
|
{
|
||||||
|
if (instance->dispatcher.SuspendThread())
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (session) session->SetUserTimer(-1.0); // interval less than zero cancels timer
|
||||||
|
instance->PurgeNotifications(sessionHandle, NORM_USER_TIMEOUT);
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end NormCancelUserTimer()
|
||||||
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
|
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
|
||||||
{
|
{
|
||||||
|
|
@ -945,6 +1090,17 @@ NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
|
||||||
return NORM_NODE_NONE;
|
return NORM_NODE_NONE;
|
||||||
} // end NormGetLocalNodeId()
|
} // end NormGetLocalNodeId()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
UINT16 NormGetRxPort(NormSessionHandle sessionHandle)
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (NULL != session)
|
||||||
|
return session->GetRxPort();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
} // end NormGetRxPort()
|
||||||
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetTxPort(NormSessionHandle sessionHandle,
|
bool NormSetTxPort(NormSessionHandle sessionHandle,
|
||||||
UINT16 txPort,
|
UINT16 txPort,
|
||||||
|
|
@ -993,7 +1149,8 @@ void NormSetTxOnly(NormSessionHandle sessionHandle,
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormChangeDestination(NormSessionHandle sessionHandle,
|
bool NormChangeDestination(NormSessionHandle sessionHandle,
|
||||||
const char* sessionAddress,
|
const char* sessionAddress,
|
||||||
UINT16 sessionPort)
|
UINT16 sessionPort,
|
||||||
|
bool connectToSessionAddress)
|
||||||
{
|
{
|
||||||
// First, see if we can make a valid ProtoAddress
|
// First, see if we can make a valid ProtoAddress
|
||||||
ProtoAddress dest;
|
ProtoAddress dest;
|
||||||
|
|
@ -1004,7 +1161,12 @@ bool NormChangeDestination(NormSessionHandle sessionHandle,
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSession* session = (NormSession*)sessionHandle;
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
if (session) session->SetAddress(dest);
|
if (session)
|
||||||
|
{
|
||||||
|
session->SetAddress(dest);
|
||||||
|
if (connectToSessionAddress)
|
||||||
|
session->SetTxOnly(session->GetTxOnly(), true);
|
||||||
|
}
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1029,16 +1191,6 @@ void NormSetRxPortReuse(NormSessionHandle sessionHandle,
|
||||||
}
|
}
|
||||||
} // end NormSetRxPortReuse()
|
} // end NormSetRxPortReuse()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
|
||||||
UINT16 NormGetRxPort(NormSessionHandle sessionHandle)
|
|
||||||
{
|
|
||||||
NormSession* session = (NormSession*)sessionHandle;
|
|
||||||
if (NULL != session)
|
|
||||||
return session->GetRxPort();
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
} // end NormGetRxPort()
|
|
||||||
|
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormSetEcnSupport(NormSessionHandle sessionHandle, bool ecnEnable, bool ignoreLoss, bool tolerateLoss)
|
void NormSetEcnSupport(NormSessionHandle sessionHandle, bool ecnEnable, bool ignoreLoss, bool tolerateLoss)
|
||||||
|
|
@ -1074,6 +1226,25 @@ bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
|
||||||
return result;
|
return result;
|
||||||
} // end NormSetMulticastInterface()
|
} // end NormSetMulticastInterface()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
bool NormSetSSM(NormSessionHandle sessionHandle,
|
||||||
|
const char* sourceAddress)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
|
if (NULL != instance)
|
||||||
|
{
|
||||||
|
if (instance->dispatcher.SuspendThread())
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (session)
|
||||||
|
result = session->SetSSM(sourceAddress);
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} // end NormSetSSM()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetTTL(NormSessionHandle sessionHandle,
|
bool NormSetTTL(NormSessionHandle sessionHandle,
|
||||||
unsigned char ttl)
|
unsigned char ttl)
|
||||||
|
|
@ -1125,6 +1296,16 @@ bool NormSetLoopback(NormSessionHandle sessionHandle, bool state)
|
||||||
} // end NormSetLoopback()
|
} // end NormSetLoopback()
|
||||||
|
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
bool NormSetMulticastLoopback(NormSessionHandle sessionHandle, bool state)
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
if (session)
|
||||||
|
return session->SetMulticastLoopback(state);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
} // end NormSetLoopback()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormSetFragmentation(NormSessionHandle sessionHandle, bool state)
|
bool NormSetFragmentation(NormSessionHandle sessionHandle, bool state)
|
||||||
{
|
{
|
||||||
|
|
@ -1263,10 +1444,10 @@ NormSessionId NormGetRandomSessionId()
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
bool NormStartSender(NormSessionHandle sessionHandle,
|
bool NormStartSender(NormSessionHandle sessionHandle,
|
||||||
NormSessionId sessionId,
|
NormSessionId sessionId,
|
||||||
UINT32 bufferSpace,
|
UINT32 bufferSpace,
|
||||||
UINT16 segmentSize,
|
UINT16 segmentSize,
|
||||||
unsigned char numData,
|
UINT16 numData,
|
||||||
unsigned char numParity)
|
UINT16 numParity)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
|
||||||
|
|
@ -1727,6 +1908,8 @@ bool NormSetWatermark(NormSessionHandle sessionHandle,
|
||||||
NormObject* obj = (NormObject*)objectHandle;
|
NormObject* obj = (NormObject*)objectHandle;
|
||||||
if (session && obj)
|
if (session && obj)
|
||||||
{
|
{
|
||||||
|
// Purge any existing to NORM_TX_WATERMARK_COMPLETED notification to be safe
|
||||||
|
instance->PurgeNotifications(sessionHandle, NORM_TX_WATERMARK_COMPLETED);
|
||||||
// (segmentId doesn't matter for non-stream)
|
// (segmentId doesn't matter for non-stream)
|
||||||
if (obj->IsStream())
|
if (obj->IsStream())
|
||||||
{
|
{
|
||||||
|
|
@ -1791,7 +1974,7 @@ bool NormAddAckingNode(NormSessionHandle sessionHandle,
|
||||||
{
|
{
|
||||||
NormSession* session = (NormSession*)sessionHandle;
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
if (session)
|
if (session)
|
||||||
result = session->SenderAddAckingNode(nodeId);
|
result = (NULL != session->SenderAddAckingNode(nodeId));
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -1810,6 +1993,20 @@ void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
||||||
}
|
}
|
||||||
} // end NormRemoveAckingNode()
|
} // end NormRemoveAckingNode()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
NormNodeHandle NormGetAckingNodeHandle(NormSessionHandle sessionHandle,
|
||||||
|
NormNodeId nodeId)
|
||||||
|
{
|
||||||
|
if (NORM_SESSION_INVALID != sessionHandle)
|
||||||
|
{
|
||||||
|
NormSession* session = (NormSession*)sessionHandle;
|
||||||
|
NormAckingNode* acker = session->SenderFindAckingNode(nodeId);
|
||||||
|
if (NULL != acker)
|
||||||
|
return ((NormNodeHandle)static_cast<NormNode*>(acker));
|
||||||
|
}
|
||||||
|
return NORM_NODE_INVALID;
|
||||||
|
} // end NormGetAckingNodeHandle()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
void NormSetAutoAckingNodes(NormSessionHandle sessionHandle,
|
void NormSetAutoAckingNodes(NormSessionHandle sessionHandle,
|
||||||
NormTrackingStatus trackingStatus)
|
NormTrackingStatus trackingStatus)
|
||||||
|
|
@ -1994,8 +2191,12 @@ void NormNodeSetUnicastNack(NormNodeHandle nodeHandle,
|
||||||
bool unicastNacks)
|
bool unicastNacks)
|
||||||
{
|
{
|
||||||
|
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
if (node) node->SetUnicastNacks(unicastNacks);
|
if ((NULL != node) && (NormNode::SENDER == node->GetType()))
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->SetUnicastNacks(unicastNacks);
|
||||||
|
}
|
||||||
} // end NormNodeSetUnicastNack()
|
} // end NormNodeSetUnicastNack()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
|
|
@ -2018,8 +2219,12 @@ NORM_API_LINKAGE
|
||||||
void NormNodeSetNackingMode(NormNodeHandle nodeHandle,
|
void NormNodeSetNackingMode(NormNodeHandle nodeHandle,
|
||||||
NormNackingMode nackingMode)
|
NormNackingMode nackingMode)
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
if (node) node->SetDefaultNackingMode((NormObject::NackingMode)nackingMode);
|
if ((NULL != node) && (NormNode::SENDER == node->GetType()))
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->SetDefaultNackingMode((NormObject::NackingMode)nackingMode);
|
||||||
|
}
|
||||||
} // end NormNodeSetNackingMode()
|
} // end NormNodeSetNackingMode()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
|
|
@ -2043,9 +2248,12 @@ NORM_API_LINKAGE
|
||||||
void NormNodeSetRepairBoundary(NormNodeHandle nodeHandle,
|
void NormNodeSetRepairBoundary(NormNodeHandle nodeHandle,
|
||||||
NormRepairBoundary repairBoundary)
|
NormRepairBoundary repairBoundary)
|
||||||
{
|
{
|
||||||
NormSenderNode* node = static_cast<NormSenderNode*>((NormSenderNode*)nodeHandle);
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
if (node)
|
if ((NULL != node) && (NormNode::SENDER == node->GetType()))
|
||||||
node->SetRepairBoundary((NormSenderNode::RepairBoundary)repairBoundary);
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->SetRepairBoundary((NormSenderNode::RepairBoundary)repairBoundary);
|
||||||
|
}
|
||||||
} // end NormNodeSetRepairBoundary()
|
} // end NormNodeSetRepairBoundary()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2071,8 +2279,12 @@ void NormNodeSetRxRobustFactor(NormNodeHandle nodeHandle,
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
node->SetRobustFactor(robustFactor);
|
if (NormNode::SENDER == node->GetType())
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->SetRobustFactor(robustFactor);
|
||||||
|
}
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2322,9 +2534,15 @@ const char* NormDataAccessData(NormObjectHandle dataHandle)
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
char* NormDataDetachData(NormObjectHandle dataHandle)
|
char* NormDataDetachData(NormObjectHandle dataHandle)
|
||||||
{
|
{
|
||||||
NormDataObject* dataObj =
|
char* ptr = NULL;
|
||||||
static_cast<NormDataObject*>((NormObject*)dataHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromObject(dataHandle);
|
||||||
return dataObj->DetachData();
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
|
{
|
||||||
|
NormDataObject* dataObj = static_cast<NormDataObject*>((NormObject*)dataHandle);
|
||||||
|
ptr = dataObj->DetachData();
|
||||||
|
instance->dispatcher.ResumeThread();
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
} // end NormDataDetachData()
|
} // end NormDataDetachData()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
|
|
@ -2339,7 +2557,7 @@ NormNodeHandle NormObjectGetSender(NormObjectHandle objectHandle)
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle)
|
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle)
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
if (NULL != node)
|
if (NULL != node)
|
||||||
return node->GetId();
|
return node->GetId();
|
||||||
else
|
else
|
||||||
|
|
@ -2355,10 +2573,10 @@ bool NormNodeGetAddress(NormNodeHandle nodeHandle,
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (NORM_NODE_INVALID != nodeHandle)
|
if (NORM_NODE_INVALID != nodeHandle)
|
||||||
{
|
{
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
//NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
//if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormSenderNode*)nodeHandle;
|
||||||
const ProtoAddress& nodeAddr = node->GetAddress();
|
const ProtoAddress& nodeAddr = node->GetAddress();
|
||||||
unsigned int addrLen = nodeAddr.GetLength();
|
unsigned int addrLen = nodeAddr.GetLength();
|
||||||
if (addrBuffer && bufferLen && (addrLen <= *bufferLen))
|
if (addrBuffer && bufferLen && (addrLen <= *bufferLen))
|
||||||
|
|
@ -2372,20 +2590,45 @@ bool NormNodeGetAddress(NormNodeHandle nodeHandle,
|
||||||
}
|
}
|
||||||
if (bufferLen) *bufferLen = addrLen;
|
if (bufferLen) *bufferLen = addrLen;
|
||||||
if (port) *port = nodeAddr.GetPort();
|
if (port) *port = nodeAddr.GetPort();
|
||||||
instance->dispatcher.ResumeThread();
|
//instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} // end NormNodeGetId()
|
} // end NormNodeGetAddress()
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
void NormNodeSetUserData(NormNodeHandle nodeHandle, const void* userData)
|
||||||
|
{
|
||||||
|
if (NORM_NODE_INVALID != nodeHandle)
|
||||||
|
{
|
||||||
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
|
return node->SetUserData(userData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NORM_API_LINKAGE
|
||||||
|
const void* NormNodeGetUserData(NormNodeHandle nodeHandle)
|
||||||
|
{
|
||||||
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
|
if (NULL != node)
|
||||||
|
return node->GetUserData();
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
} // end NormNodeGetUserData()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
double NormNodeGetGrtt(NormNodeHandle nodeHandle)
|
double NormNodeGetGrtt(NormNodeHandle nodeHandle)
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
if (NULL != node)
|
if ((NULL != node) && (NormNode::SENDER == node->GetType()))
|
||||||
return node->GetGrttEstimate();
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
return sender->GetGrttEstimate();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return -1.0;
|
return -1.0;
|
||||||
|
}
|
||||||
} // end NormNodeGetGrtt()
|
} // end NormNodeGetGrtt()
|
||||||
|
|
||||||
NORM_API_LINKAGE
|
NORM_API_LINKAGE
|
||||||
|
|
@ -2399,8 +2642,12 @@ bool NormNodeGetCommand(NormNodeHandle nodeHandle,
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
result = node->ReadNextCmd(cmdBuffer, cmdLength);
|
if (NormNode::SENDER == node->GetType())
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
result = sender->ReadNextCmd(cmdBuffer, cmdLength);
|
||||||
|
}
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2415,8 +2662,14 @@ void NormNodeFreeBuffers(NormNodeHandle nodeHandle)
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
node->FreeBuffers();
|
if (NormNode::SENDER == node->GetType())
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->FreeBuffers();
|
||||||
|
// Since this results in aborted objects, should we purge those object notifications?
|
||||||
|
// or let the be delivered since the app may have associate state
|
||||||
|
}
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2430,8 +2683,14 @@ void NormNodeDelete(NormNodeHandle nodeHandle)
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
NormSenderNode* node = (NormSenderNode*)nodeHandle;
|
NormNode* node = (NormNode*)nodeHandle;
|
||||||
node->GetSession().DeleteRemoteSender(*node);
|
if (NormNode::SENDER == node->GetType())
|
||||||
|
{
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(node);
|
||||||
|
sender->GetSession().DeleteRemoteSender(*sender);
|
||||||
|
}
|
||||||
|
// else if NormNode::ACKER, should we remove from acking node list???
|
||||||
|
instance->PurgeNodeNotifications(nodeHandle);
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2445,7 +2704,7 @@ void NormNodeRetain(NormNodeHandle nodeHandle)
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
((NormSenderNode*)nodeHandle)->Retain();
|
((NormNode*)nodeHandle)->Retain();
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2459,7 +2718,7 @@ void NormNodeRelease(NormNodeHandle nodeHandle)
|
||||||
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
|
||||||
if (instance && instance->dispatcher.SuspendThread())
|
if (instance && instance->dispatcher.SuspendThread())
|
||||||
{
|
{
|
||||||
((NormSenderNode*)nodeHandle)->Release();
|
((NormNode*)nodeHandle)->Release();
|
||||||
instance->dispatcher.ResumeThread();
|
instance->dispatcher.ResumeThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class NormApp : public NormController, public ProtoApp
|
||||||
virtual void Notify(NormController::Event event,
|
virtual void Notify(NormController::Event event,
|
||||||
class NormSessionMgr* sessionMgr,
|
class NormSessionMgr* sessionMgr,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* node,
|
||||||
class NormObject* object);
|
class NormObject* object);
|
||||||
|
|
||||||
bool OnIntervalTimeout(ProtoTimer& theTimer);
|
bool OnIntervalTimeout(ProtoTimer& theTimer);
|
||||||
|
|
@ -490,8 +490,9 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
||||||
len = strlen(buffer);
|
len = strlen(buffer);
|
||||||
len = (len > 8191) ? 8191 : len;
|
len = (len > 8191) ? 8191 : len;
|
||||||
buffer[len++] = '\0';
|
buffer[len++] = '\0';
|
||||||
if (!control_pipe.Send(buffer, (unsigned int&)len))
|
unsigned int numBytes = (unsigned int)len;
|
||||||
{
|
if (!control_pipe.Send(buffer, numBytes))
|
||||||
|
{
|
||||||
PLOG(PL_FATAL, "NormApp::OnCommand() error sending command to remote instance\n");
|
PLOG(PL_FATAL, "NormApp::OnCommand() error sending command to remote instance\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1494,7 +1495,7 @@ void NormApp::OnInputReady()
|
||||||
void NormApp::Notify(NormController::Event event,
|
void NormApp::Notify(NormController::Event event,
|
||||||
class NormSessionMgr* sessionMgr,
|
class NormSessionMgr* sessionMgr,
|
||||||
class NormSession* session,
|
class NormSession* session,
|
||||||
class NormSenderNode* sender,
|
class NormNode* sender,
|
||||||
class NormObject* object)
|
class NormObject* object)
|
||||||
{
|
{
|
||||||
switch (event)
|
switch (event)
|
||||||
|
|
@ -1558,7 +1559,8 @@ void NormApp::Notify(NormController::Event event,
|
||||||
|
|
||||||
case REMOTE_SENDER_INACTIVE:
|
case REMOTE_SENDER_INACTIVE:
|
||||||
PLOG(PL_DEBUG, "NormApp::Notify(REMOTE_SENDER_INACTIVE) ...\n");
|
PLOG(PL_DEBUG, "NormApp::Notify(REMOTE_SENDER_INACTIVE) ...\n");
|
||||||
if (!rx_persistent) sender->FreeBuffers();
|
if (!rx_persistent)
|
||||||
|
static_cast<NormSenderNode*>(sender)->FreeBuffers();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -764,13 +764,13 @@ int NormDecoderRS16::Decode(char** vectorList, unsigned int numData, unsigned i
|
||||||
bool NormDecoderRS16::InvertDecodingMatrix()
|
bool NormDecoderRS16::InvertDecodingMatrix()
|
||||||
{
|
{
|
||||||
gf* src = (gf*)dec_matrix;
|
gf* src = (gf*)dec_matrix;
|
||||||
int k = ndata;
|
unsigned int k = ndata;
|
||||||
|
|
||||||
memset(inv_id_row, 0, k*sizeof(gf));
|
memset(inv_id_row, 0, k*sizeof(gf));
|
||||||
// inv_pivt marks elements already used as pivots.
|
// inv_pivt marks elements already used as pivots.
|
||||||
memset(inv_pivt, 0, k*sizeof(unsigned int));
|
memset(inv_pivt, 0, k*sizeof(unsigned int));
|
||||||
|
|
||||||
for (int col = 0; col < k ; col++)
|
for (unsigned int col = 0; col < k ; col++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Zeroing column 'col', look for a non-zero element.
|
* Zeroing column 'col', look for a non-zero element.
|
||||||
|
|
@ -788,7 +788,7 @@ bool NormDecoderRS16::InvertDecodingMatrix()
|
||||||
{
|
{
|
||||||
if (inv_pivt[row] != 1)
|
if (inv_pivt[row] != 1)
|
||||||
{
|
{
|
||||||
for (int ix = 0 ; ix < k ; ix++)
|
for (unsigned int ix = 0 ; ix < k ; ix++)
|
||||||
{
|
{
|
||||||
if (inv_pivt[ix] == 0)
|
if (inv_pivt[ix] == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -821,7 +821,7 @@ bool NormDecoderRS16::InvertDecodingMatrix()
|
||||||
*/
|
*/
|
||||||
if (irow != icol)
|
if (irow != icol)
|
||||||
{
|
{
|
||||||
for (int ix = 0 ; ix < k ; ix++ )
|
for (unsigned int ix = 0 ; ix < k ; ix++ )
|
||||||
SWAP(src[irow*k + ix], src[icol*k + ix], gf);
|
SWAP(src[irow*k + ix], src[icol*k + ix], gf);
|
||||||
}
|
}
|
||||||
inv_ndxr[col] = irow ;
|
inv_ndxr[col] = irow ;
|
||||||
|
|
@ -841,7 +841,7 @@ bool NormDecoderRS16::InvertDecodingMatrix()
|
||||||
*/
|
*/
|
||||||
c = inverse[ c ] ;
|
c = inverse[ c ] ;
|
||||||
pivotRow[icol] = 1 ;
|
pivotRow[icol] = 1 ;
|
||||||
for (int ix = 0 ; ix < k ; ix++ )
|
for (unsigned int ix = 0 ; ix < k ; ix++ )
|
||||||
pivotRow[ix] = gf_mul(c, pivotRow[ix] );
|
pivotRow[ix] = gf_mul(c, pivotRow[ix] );
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -869,11 +869,11 @@ bool NormDecoderRS16::InvertDecodingMatrix()
|
||||||
|
|
||||||
for (int col = k - 1 ; col >= 0 ; col-- )
|
for (int col = k - 1 ; col >= 0 ; col-- )
|
||||||
{
|
{
|
||||||
if (inv_ndxr[col] < 0 || inv_ndxr[col] >= (unsigned int)k)
|
if (inv_ndxr[col] >= k)
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormDecoderRS16::InvertDecodingMatrix() error: AARGH, inv_ndxr[col] %d\n", inv_ndxr[col]);
|
PLOG(PL_ERROR, "NormDecoderRS16::InvertDecodingMatrix() error: AARGH, inv_ndxr[col] %d\n", inv_ndxr[col]);
|
||||||
}
|
}
|
||||||
else if (inv_ndxc[col] <0 || inv_ndxc[col] >= (unsigned int)k)
|
else if (inv_ndxc[col] >= k)
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormDecoderRS16::InvertDecodingMatrix() error: AARGH, indxc[col] %d\n", inv_ndxc[col]);
|
PLOG(PL_ERROR, "NormDecoderRS16::InvertDecodingMatrix() error: AARGH, indxc[col] %d\n", inv_ndxc[col]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GF_BITS 8 // 8-bit RS code
|
#define GF_BITS 8 // 8-bit RS code
|
||||||
#if (GF_BITS < 2 && GF_BITS > 16)
|
#if (GF_BITS < 2) || (GF_BITS > 16)
|
||||||
#error "GF_BITS must be 2 .. 16"
|
#error "GF_BITS must be 2 .. 16"
|
||||||
#endif
|
#endif
|
||||||
#if (GF_BITS <= 8)
|
#if (GF_BITS <= 8)
|
||||||
|
|
@ -766,13 +766,13 @@ int NormDecoderRS8::Decode(char** vectorList, unsigned int numData, unsigned in
|
||||||
bool NormDecoderRS8::InvertDecodingMatrix()
|
bool NormDecoderRS8::InvertDecodingMatrix()
|
||||||
{
|
{
|
||||||
gf* src = (gf*)dec_matrix;
|
gf* src = (gf*)dec_matrix;
|
||||||
int k = ndata;
|
unsigned int k = ndata;
|
||||||
|
|
||||||
memset(inv_id_row, 0, k*sizeof(gf));
|
memset(inv_id_row, 0, k*sizeof(gf));
|
||||||
// inv_pivt marks elements already used as pivots.
|
// inv_pivt marks elements already used as pivots.
|
||||||
memset(inv_pivt, 0, k*sizeof(unsigned int));
|
memset(inv_pivt, 0, k*sizeof(unsigned int));
|
||||||
|
|
||||||
for (int col = 0; col < k ; col++)
|
for (unsigned int col = 0; col < k ; col++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Zeroing column 'col', look for a non-zero element.
|
* Zeroing column 'col', look for a non-zero element.
|
||||||
|
|
@ -786,11 +786,11 @@ bool NormDecoderRS8::InvertDecodingMatrix()
|
||||||
icol = col ;
|
icol = col ;
|
||||||
goto found_piv ;
|
goto found_piv ;
|
||||||
}
|
}
|
||||||
for (int row = 0 ; row < k ; row++)
|
for (unsigned int row = 0 ; row < k ; row++)
|
||||||
{
|
{
|
||||||
if (inv_pivt[row] != 1)
|
if (inv_pivt[row] != 1)
|
||||||
{
|
{
|
||||||
for (int ix = 0 ; ix < k ; ix++)
|
for (unsigned int ix = 0 ; ix < k ; ix++)
|
||||||
{
|
{
|
||||||
if (inv_pivt[ix] == 0)
|
if (inv_pivt[ix] == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -823,7 +823,7 @@ bool NormDecoderRS8::InvertDecodingMatrix()
|
||||||
*/
|
*/
|
||||||
if (irow != icol)
|
if (irow != icol)
|
||||||
{
|
{
|
||||||
for (int ix = 0 ; ix < k ; ix++ )
|
for (unsigned int ix = 0 ; ix < k ; ix++ )
|
||||||
SWAP(src[irow*k + ix], src[icol*k + ix], gf);
|
SWAP(src[irow*k + ix], src[icol*k + ix], gf);
|
||||||
}
|
}
|
||||||
inv_ndxr[col] = irow ;
|
inv_ndxr[col] = irow ;
|
||||||
|
|
@ -843,7 +843,7 @@ bool NormDecoderRS8::InvertDecodingMatrix()
|
||||||
*/
|
*/
|
||||||
c = inverse[ c ] ;
|
c = inverse[ c ] ;
|
||||||
pivotRow[icol] = 1 ;
|
pivotRow[icol] = 1 ;
|
||||||
for (int ix = 0 ; ix < k ; ix++ )
|
for (unsigned int ix = 0 ; ix < k ; ix++ )
|
||||||
pivotRow[ix] = gf_mul(c, pivotRow[ix] );
|
pivotRow[ix] = gf_mul(c, pivotRow[ix] );
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -871,17 +871,17 @@ bool NormDecoderRS8::InvertDecodingMatrix()
|
||||||
|
|
||||||
for (int col = k - 1 ; col >= 0 ; col-- )
|
for (int col = k - 1 ; col >= 0 ; col-- )
|
||||||
{
|
{
|
||||||
if (inv_ndxr[col] < 0 || inv_ndxr[col] >= (unsigned int)k)
|
if (inv_ndxr[col] >= k)
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormDecoderRS8::InvertDecodingMatrix() error: AARGH, inv_ndxr[col] %d\n", inv_ndxr[col]);
|
PLOG(PL_ERROR, "NormDecoderRS8::InvertDecodingMatrix() error: AARGH, inv_ndxr[col] %d\n", inv_ndxr[col]);
|
||||||
}
|
}
|
||||||
else if (inv_ndxc[col] <0 || inv_ndxc[col] >= (unsigned int)k)
|
else if (inv_ndxc[col] >= k)
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormDecoderRS8::InvertDecodingMatrix() error: AARGH, indxc[col] %d\n", inv_ndxc[col]);
|
PLOG(PL_ERROR, "NormDecoderRS8::InvertDecodingMatrix() error: AARGH, indxc[col] %d\n", inv_ndxc[col]);
|
||||||
}
|
}
|
||||||
else if (inv_ndxr[col] != inv_ndxc[col] )
|
else if (inv_ndxr[col] != inv_ndxc[col] )
|
||||||
{
|
{
|
||||||
for (int row = 0 ; row < k ; row++ )
|
for (unsigned int row = 0 ; row < k ; row++ )
|
||||||
SWAP( src[row*k + inv_ndxr[col]], src[row*k + inv_ndxc[col]], gf) ;
|
SWAP( src[row*k + inv_ndxr[col]], src[row*k + inv_ndxc[col]], gf) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include "normEncoderRS8.h" // 8-bit Reed-Solomon encoder of RFC 5510
|
#include "normEncoderRS8.h" // 8-bit Reed-Solomon encoder of RFC 5510
|
||||||
#include "normEncoderRS16.h" // 16-bit Reed-Solomon encoder of RFC 5510
|
#include "normEncoderRS16.h" // 16-bit Reed-Solomon encoder of RFC 5510
|
||||||
|
|
||||||
NormNode::NormNode(class NormSession& theSession, NormNodeId nodeId)
|
NormNode::NormNode(Type nodeType, class NormSession& theSession, NormNodeId nodeId)
|
||||||
: session(theSession), id(nodeId), reference_count(1),
|
: session(theSession), node_type(nodeType), id(nodeId), reference_count(1), user_data(NULL),
|
||||||
parent(NULL), right(NULL), left(NULL)
|
parent(NULL), right(NULL), left(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -14,8 +14,10 @@ NormNode::NormNode(class NormSession& theSession, NormNodeId nodeId)
|
||||||
|
|
||||||
NormNode::~NormNode()
|
NormNode::~NormNode()
|
||||||
{
|
{
|
||||||
|
//TRACE("NormNode %lu dtor ...\n", (unsigned long)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NormNode::Retain()
|
void NormNode::Retain()
|
||||||
{
|
{
|
||||||
reference_count++;
|
reference_count++;
|
||||||
|
|
@ -40,9 +42,8 @@ NormNode::Accumulator::Accumulator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NormCCNode::NormCCNode(class NormSession& theSession, NormNodeId nodeId)
|
NormCCNode::NormCCNode(class NormSession& theSession, NormNodeId nodeId)
|
||||||
: NormNode(theSession, nodeId)
|
: NormNode(CC_NODE, theSession, nodeId)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -65,11 +66,11 @@ const double NormSenderNode::DEFAULT_NOMINAL_INTERVAL = 2*NormSession::DEFAULT_G
|
||||||
const double NormSenderNode::ACTIVITY_INTERVAL_MIN = 1.0; // 1 second min activity timeout
|
const double NormSenderNode::ACTIVITY_INTERVAL_MIN = 1.0; // 1 second min activity timeout
|
||||||
|
|
||||||
NormSenderNode::NormSenderNode(class NormSession& theSession, NormNodeId nodeId)
|
NormSenderNode::NormSenderNode(class NormSession& theSession, NormNodeId nodeId)
|
||||||
: NormNode(theSession, nodeId), instance_id(0), robust_factor(session.GetRxRobustFactor()),
|
: NormNode(SENDER, theSession, nodeId), instance_id(0), robust_factor(session.GetRxRobustFactor()),
|
||||||
synchronized(false), sync_id(0),
|
synchronized(false), sync_id(0),
|
||||||
is_open(false), segment_size(0), fec_m(0), ndata(0), nparity(0),
|
is_open(false), segment_size(0), fec_m(0), ndata(0), nparity(0),
|
||||||
repair_boundary(BLOCK_BOUNDARY), decoder(NULL), erasure_loc(NULL),
|
repair_boundary(BLOCK_BOUNDARY), decoder(NULL), erasure_loc(NULL),
|
||||||
retrieval_loc(NULL), retrieval_pool(NULL),
|
retrieval_loc(NULL), retrieval_pool(NULL), ack_pending(false),
|
||||||
cc_sequence(0), cc_enable(false), cc_feedback_needed(false), cc_rate(0.0),
|
cc_sequence(0), cc_enable(false), cc_feedback_needed(false), cc_rate(0.0),
|
||||||
rtt_confirmed(false), is_clr(false), is_plr(false),
|
rtt_confirmed(false), is_clr(false), is_plr(false),
|
||||||
slow_start(true), send_rate(0.0), recv_rate(0.0), recv_rate_prev(0.0),
|
slow_start(true), send_rate(0.0), recv_rate(0.0), recv_rate_prev(0.0),
|
||||||
|
|
@ -160,6 +161,7 @@ void NormSenderNode::Close()
|
||||||
if (activity_timer.IsActive()) activity_timer.Deactivate();
|
if (activity_timer.IsActive()) activity_timer.Deactivate();
|
||||||
if (repair_timer.IsActive()) repair_timer.Deactivate();
|
if (repair_timer.IsActive()) repair_timer.Deactivate();
|
||||||
if (cc_timer.IsActive()) cc_timer.Deactivate();
|
if (cc_timer.IsActive()) cc_timer.Deactivate();
|
||||||
|
if (ack_timer.IsActive()) ack_timer.Deactivate();
|
||||||
FreeBuffers();
|
FreeBuffers();
|
||||||
|
|
||||||
// Delete any command buffers from cmd_buffer queue
|
// Delete any command buffers from cmd_buffer queue
|
||||||
|
|
@ -566,7 +568,7 @@ void NormSenderNode::HandleCommand(const struct timeval& currentTime,
|
||||||
}
|
}
|
||||||
// 1) Sync to squelch (discards all objects prior to squelch objectId)
|
// 1) Sync to squelch (discards all objects prior to squelch objectId)
|
||||||
NormObjectId objectId = squelch.GetObjectId();
|
NormObjectId objectId = squelch.GetObjectId();
|
||||||
Sync(objectId);
|
Sync(objectId);
|
||||||
// 2) Prune stream object if applicable
|
// 2) Prune stream object if applicable
|
||||||
NormObject* obj = rx_table.Find(objectId);
|
NormObject* obj = rx_table.Find(objectId);
|
||||||
if ((NULL != obj) && (NormObject::STREAM == obj->GetType()))
|
if ((NULL != obj) && (NormObject::STREAM == obj->GetType()))
|
||||||
|
|
@ -638,7 +640,6 @@ void NormSenderNode::HandleCommand(const struct timeval& currentTime,
|
||||||
is_clr = is_plr = false;
|
is_clr = is_plr = false;
|
||||||
}
|
}
|
||||||
double maxBackoff;
|
double maxBackoff;
|
||||||
|
|
||||||
if (is_clr || is_plr || !session.Address().IsMulticast())
|
if (is_clr || is_plr || !session.Address().IsMulticast())
|
||||||
{
|
{
|
||||||
// Respond immediately (i.e., no backoff, holdoff etc)
|
// Respond immediately (i.e., no backoff, holdoff etc)
|
||||||
|
|
@ -757,6 +758,7 @@ void NormSenderNode::HandleCommand(const struct timeval& currentTime,
|
||||||
{
|
{
|
||||||
double ackBackoff = session.Address().IsMulticast() ? UniformRand(grtt_estimate) : 0.0;
|
double ackBackoff = session.Address().IsMulticast() ? UniformRand(grtt_estimate) : 0.0;
|
||||||
ack_timer.SetInterval(ackBackoff);
|
ack_timer.SetInterval(ackBackoff);
|
||||||
|
ack_pending = true;
|
||||||
session.ActivateTimer(ack_timer);
|
session.ActivateTimer(ack_timer);
|
||||||
}
|
}
|
||||||
break; // no pending repairs, skip regular "RepairCheck"
|
break; // no pending repairs, skip regular "RepairCheck"
|
||||||
|
|
@ -1546,9 +1548,7 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
|
||||||
break;
|
break;
|
||||||
} // end switch(status)
|
} // end switch(status)
|
||||||
|
|
||||||
|
if (NULL != obj)
|
||||||
|
|
||||||
if (obj)
|
|
||||||
{
|
{
|
||||||
obj->HandleObjectMessage(msg, msgType, blockId, segmentId);
|
obj->HandleObjectMessage(msg, msgType, blockId, segmentId);
|
||||||
|
|
||||||
|
|
@ -1742,11 +1742,9 @@ NormSenderNode::ObjectStatus NormSenderNode::UpdateSyncStatus(const NormObjectId
|
||||||
{
|
{
|
||||||
NormObjectId lastPending(65535);
|
NormObjectId lastPending(65535);
|
||||||
GetLastPending(lastPending);
|
GetLastPending(lastPending);
|
||||||
TRACE("lp:%hu\n", (UINT16)lastPending);
|
|
||||||
if (syncId > lastPending)
|
if (syncId > lastPending)
|
||||||
{
|
{
|
||||||
UINT16 delta = syncId - lastPending;
|
UINT16 delta = syncId - lastPending;
|
||||||
TRACE("SYNC DELTA = %d\n", delta);
|
|
||||||
if (delta < max_pending_range)
|
if (delta < max_pending_range)
|
||||||
{
|
{
|
||||||
syncId -= (max_pending_range - 1);
|
syncId -= (max_pending_range - 1);
|
||||||
|
|
@ -2179,7 +2177,6 @@ bool NormSenderNode::OnRepairTimeout(ProtoTimer& /*theTimer*/)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != obj)
|
if (NULL != obj)
|
||||||
{
|
{
|
||||||
if (obj->IsPending(nextId != max_pending_object))
|
if (obj->IsPending(nextId != max_pending_object))
|
||||||
|
|
@ -2401,8 +2398,8 @@ bool NormSenderNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
}
|
}
|
||||||
else if (0 == activity_timer.GetRepeatCount())
|
else if (0 == activity_timer.GetRepeatCount())
|
||||||
{
|
{
|
||||||
// Serve completely inactive?
|
// Remote sender completely inactive?
|
||||||
PLOG(PL_ERROR, "NormSenderNode::OnActivityTimeout() node>%lu sender>%lu gone inactive?\n",
|
PLOG(PL_INFO, "NormSenderNode::OnActivityTimeout() node>%lu sender>%lu gone inactive?\n",
|
||||||
LocalNodeId(), GetId());
|
LocalNodeId(), GetId());
|
||||||
//FreeBuffers(); This now needs to be done by the app as of norm version 1.4b3
|
//FreeBuffers(); This now needs to be done by the app as of norm version 1.4b3
|
||||||
session.Notify(NormController::REMOTE_SENDER_INACTIVE, this, NULL);
|
session.Notify(NormController::REMOTE_SENDER_INACTIVE, this, NULL);
|
||||||
|
|
@ -2419,7 +2416,7 @@ bool NormSenderNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
NormObject* objMax = rx_table.Find(max_pending_object);
|
NormObject* objMax = rx_table.Find(max_pending_object);
|
||||||
if (NULL != objMax)
|
if (NULL != objMax)
|
||||||
{
|
{
|
||||||
/*NormSegmentId segMax = objMax->GetMaxPendingSegmentId();
|
NormSegmentId segMax = objMax->GetMaxPendingSegmentId();
|
||||||
if (0 != segMax)
|
if (0 != segMax)
|
||||||
RepairCheck(NormObject::THRU_SEGMENT,
|
RepairCheck(NormObject::THRU_SEGMENT,
|
||||||
max_pending_object,
|
max_pending_object,
|
||||||
|
|
@ -2429,10 +2426,14 @@ bool NormSenderNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
RepairCheck(NormObject::TO_BLOCK,
|
RepairCheck(NormObject::TO_BLOCK,
|
||||||
max_pending_object,
|
max_pending_object,
|
||||||
objMax->GetMaxPendingBlockId(),
|
objMax->GetMaxPendingBlockId(),
|
||||||
0);*/
|
0);
|
||||||
// Let's try this instead
|
|
||||||
RepairCheck(NormObject::THRU_OBJECT, // (TBD) thru object???
|
// The above has been reinstated because the alternative "THRU_OBJECT" here
|
||||||
max_pending_object, 0, 0);
|
// causes gratuitous NACKing when the sender goes IDLE ..
|
||||||
|
|
||||||
|
// Or we could do this instead (possibly some unnecessary NACKing for NORM_OBJECT_STREAM will occur here)
|
||||||
|
//RepairCheck(NormObject::THRU_OBJECT, // (TBD) thru object???
|
||||||
|
// max_pending_object, 0, 0);
|
||||||
|
|
||||||
// (TBD) What should we really do here? Our current NormNode::RepairCheck() and
|
// (TBD) What should we really do here? Our current NormNode::RepairCheck() and
|
||||||
// NormObject::ReceiverRepairCheck() methods update the "max_pending" indices
|
// NormObject::ReceiverRepairCheck() methods update the "max_pending" indices
|
||||||
|
|
@ -2445,7 +2446,12 @@ bool NormSenderNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
// I guess the activity timeout NACK isn't perfect ... but could help some
|
// I guess the activity timeout NACK isn't perfect ... but could help some
|
||||||
// so we leave it as it is for the moment ("THRU_OBJECT") ... perhaps we could
|
// so we leave it as it is for the moment ("THRU_OBJECT") ... perhaps we could
|
||||||
// add a parameter so NormObject::ReceiverRepairCheck() doesn't update its
|
// add a parameter so NormObject::ReceiverRepairCheck() doesn't update its
|
||||||
// "max_pending" indices - or would this break NACK building
|
// "max_pending" indices - or would this break NACK building?
|
||||||
|
|
||||||
|
// Maybe we should do THRU_OBJECT when the remote sender is fully inactive as
|
||||||
|
// opposed to this inactivity timeout that only pays attend to NORM_DATA. I.e.,
|
||||||
|
// do the above refined RepairCheck() when we still have NORM_CMD activity but
|
||||||
|
// no NORM_DATA activity??? We'd still have potentially a lot of EOT NACKing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2455,7 +2461,7 @@ bool NormSenderNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
// max_pending_object, 0, 0);
|
// max_pending_object, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We manually managed the "repeat_count" here to avoid the
|
// We manually manage the "repeat_count" here to avoid the
|
||||||
// case where "bursty" receiver scheduling may lead to false
|
// case where "bursty" receiver scheduling may lead to false
|
||||||
// inactivity indication
|
// inactivity indication
|
||||||
int repeatCount = activity_timer.GetRepeatCount();
|
int repeatCount = activity_timer.GetRepeatCount();
|
||||||
|
|
@ -2572,6 +2578,14 @@ void NormSenderNode::AttachCCFeedback(NormAckMsg& ack)
|
||||||
bool NormSenderNode::OnCCTimeout(ProtoTimer& /*theTimer*/)
|
bool NormSenderNode::OnCCTimeout(ProtoTimer& /*theTimer*/)
|
||||||
{
|
{
|
||||||
// Build and send NORM_ACK(CC)
|
// Build and send NORM_ACK(CC)
|
||||||
|
if (ack_pending && (1 == cc_timer.GetRepeatCount()))
|
||||||
|
{
|
||||||
|
// Send ACK flush right away (CC feedback is included
|
||||||
|
if (ack_timer.IsActive()) ack_timer.Deactivate();
|
||||||
|
if (cc_timer.IsActive()) cc_timer.Deactivate(); // will be reactivated if needed
|
||||||
|
OnAckTimeout(ack_timer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
switch (cc_timer.GetRepeatCount())
|
switch (cc_timer.GetRepeatCount())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -2601,23 +2615,31 @@ bool NormSenderNode::OnCCTimeout(ProtoTimer& /*theTimer*/)
|
||||||
ack->SetDestination(GetAddress());
|
ack->SetDestination(GetAddress());
|
||||||
else
|
else
|
||||||
ack->SetDestination(session.Address());
|
ack->SetDestination(session.Address());
|
||||||
session.SendMessage(*ack);
|
bool success = session.SendMessage(*ack);
|
||||||
session.ReturnMessageToPool(ack);
|
session.ReturnMessageToPool(ack);
|
||||||
cc_feedback_needed = false;
|
if (success)
|
||||||
|
|
||||||
// Begin cc_timer "holdoff" phase
|
|
||||||
if (!is_clr && !is_plr && session.Address().IsMulticast())
|
|
||||||
{
|
{
|
||||||
cc_timer.SetInterval(grtt_estimate*backoff_factor);
|
cc_feedback_needed = false;
|
||||||
return true;
|
// Begin cc_timer "holdoff" phase
|
||||||
|
if (!is_clr && !is_plr && session.Address().IsMulticast())
|
||||||
|
{
|
||||||
|
cc_timer.SetInterval(grtt_estimate*backoff_factor);
|
||||||
|
}
|
||||||
|
else if (cc_timer.IsActive())
|
||||||
|
{
|
||||||
|
cc_timer.Deactivate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (cc_timer.IsActive())
|
else
|
||||||
{
|
{
|
||||||
cc_timer.Deactivate();
|
// TBD - queue ack so it gets send retry?
|
||||||
|
PLOG(PL_ERROR, "NormSenderNode::OnCCTimeout() error: SendMessage(ack) failure\n");
|
||||||
|
if (cc_timer.IsActive()) cc_timer.Deactivate();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Should never occur
|
// Should never occur
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
|
@ -2630,7 +2652,7 @@ bool NormSenderNode::OnAckTimeout(ProtoTimer& /*theTimer*/)
|
||||||
{
|
{
|
||||||
// Build and send NORM_ACK(FLUSH)
|
// Build and send NORM_ACK(FLUSH)
|
||||||
NormAckFlushMsg* ack = (NormAckFlushMsg*)session.GetMessageFromPool();
|
NormAckFlushMsg* ack = (NormAckFlushMsg*)session.GetMessageFromPool();
|
||||||
if (ack)
|
if (NULL != ack)
|
||||||
{
|
{
|
||||||
ack->Init();
|
ack->Init();
|
||||||
ack->SetSenderId(GetId());
|
ack->SetSenderId(GetId());
|
||||||
|
|
@ -2657,24 +2679,31 @@ bool NormSenderNode::OnAckTimeout(ProtoTimer& /*theTimer*/)
|
||||||
ack->SetDestination(session.Address());
|
ack->SetDestination(session.Address());
|
||||||
|
|
||||||
// Don't rate limit feedback messages
|
// Don't rate limit feedback messages
|
||||||
session.SendMessage(*ack);
|
if (session.SendMessage(*ack))
|
||||||
session.ReturnMessageToPool(ack);
|
{
|
||||||
cc_feedback_needed = false;
|
ack_pending = false;
|
||||||
if (cc_enable && !is_clr && !is_plr && session.Address().IsMulticast())
|
cc_feedback_needed = false;
|
||||||
|
if (cc_enable && !is_clr && !is_plr && session.Address().IsMulticast())
|
||||||
|
{
|
||||||
|
// Install cc feedback holdoff
|
||||||
|
cc_timer.SetInterval(grtt_estimate*backoff_factor);
|
||||||
|
if (cc_timer.IsActive())
|
||||||
|
cc_timer.Reschedule();
|
||||||
|
else
|
||||||
|
session.ActivateTimer(cc_timer);
|
||||||
|
cc_timer.DecrementRepeatCount(); // put timer into "holdoff" phase
|
||||||
|
}
|
||||||
|
else if (cc_timer.IsActive())
|
||||||
|
{
|
||||||
|
cc_timer.Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Install cc feedback holdoff
|
// TBD - should we queue the message so it can get a send retry?
|
||||||
cc_timer.SetInterval(grtt_estimate*backoff_factor);
|
PLOG(PL_ERROR, "NormSenderNode::OnAckTimeout() error: SendMessage(ack) failure\n");
|
||||||
if (cc_timer.IsActive())
|
|
||||||
cc_timer.Reschedule();
|
|
||||||
else
|
|
||||||
session.ActivateTimer(cc_timer);
|
|
||||||
cc_timer.DecrementRepeatCount(); // put timer into "holdoff" phase
|
|
||||||
}
|
|
||||||
else if (cc_timer.IsActive())
|
|
||||||
{
|
|
||||||
cc_timer.Deactivate();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
session.ReturnMessageToPool(ack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2685,7 +2714,7 @@ bool NormSenderNode::OnAckTimeout(ProtoTimer& /*theTimer*/)
|
||||||
|
|
||||||
|
|
||||||
NormAckingNode::NormAckingNode(class NormSession& theSession, NormNodeId nodeId)
|
NormAckingNode::NormAckingNode(class NormSession& theSession, NormNodeId nodeId)
|
||||||
: NormNode(theSession, nodeId), ack_received(false), req_count(theSession.GetTxRobustFactor())
|
: NormNode(ACKER, theSession, nodeId), ack_received(false), req_count(theSession.GetTxRobustFactor())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ void NormObject::Retain()
|
||||||
|
|
||||||
void NormObject::Release()
|
void NormObject::Release()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//if ((NULL != sender) && (reference_count == 1))
|
||||||
|
// TRACE("NormObject final release node>%lu object>%hu\n", (unsigned long)sender->GetId(), (unsigned short)transport_id);
|
||||||
|
|
||||||
if (sender) sender->Release();
|
if (sender) sender->Release();
|
||||||
if (reference_count)
|
if (reference_count)
|
||||||
{
|
{
|
||||||
|
|
@ -235,7 +239,7 @@ void NormObject::Close()
|
||||||
NormObjectSize NormObject::GetBytesPending() const
|
NormObjectSize NormObject::GetBytesPending() const
|
||||||
{
|
{
|
||||||
NormBlockId nextId;
|
NormBlockId nextId;
|
||||||
if (GetFirstPending(nextId))
|
if (!IsStream() && GetFirstPending(nextId))
|
||||||
{
|
{
|
||||||
NormObjectSize largeBlockBytes = NormObjectSize(large_block_size) *
|
NormObjectSize largeBlockBytes = NormObjectSize(large_block_size) *
|
||||||
NormObjectSize(segment_size);
|
NormObjectSize(segment_size);
|
||||||
|
|
@ -264,7 +268,7 @@ NormObjectSize NormObject::GetBytesPending() const
|
||||||
{
|
{
|
||||||
return NormObjectSize(0);
|
return NormObjectSize(0);
|
||||||
}
|
}
|
||||||
} // end NormObject::GetBytesCompleted()
|
} // end NormObject::GetBytesPending()
|
||||||
|
|
||||||
// Used by sender
|
// Used by sender
|
||||||
bool NormObject::HandleInfoRequest(bool holdoff)
|
bool NormObject::HandleInfoRequest(bool holdoff)
|
||||||
|
|
@ -824,7 +828,7 @@ bool NormObject::ReceiverRepairCheck(CheckLevel level,
|
||||||
if (segmentId >= max_pending_segment)
|
if (segmentId >= max_pending_segment)
|
||||||
max_pending_segment = segmentId + 1;
|
max_pending_segment = segmentId + 1;
|
||||||
}
|
}
|
||||||
if (blockId == final_block_id)
|
if (!IsStream() && (blockId == final_block_id))
|
||||||
{
|
{
|
||||||
unsigned int finalSegment = GetBlockSize(blockId) - 1;
|
unsigned int finalSegment = GetBlockSize(blockId) - 1;
|
||||||
if (finalSegment <= segmentId)
|
if (finalSegment <= segmentId)
|
||||||
|
|
@ -858,7 +862,6 @@ bool NormObject::ReceiverRepairCheck(CheckLevel level,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
NormBlockId firstPending;
|
NormBlockId firstPending;
|
||||||
if (GetFirstPending(firstPending))
|
if (GetFirstPending(firstPending))
|
||||||
{
|
{
|
||||||
|
|
@ -901,7 +904,7 @@ bool NormObject::ReceiverRepairCheck(CheckLevel level,
|
||||||
max_pending_block = blockId;
|
max_pending_block = blockId;
|
||||||
max_pending_segment = GetBlockSize(blockId);
|
max_pending_segment = GetBlockSize(blockId);
|
||||||
}
|
}
|
||||||
if (blockId == final_block_id)
|
if (!IsStream() && (blockId == final_block_id))
|
||||||
thruObject = true;
|
thruObject = true;
|
||||||
if (timerActive)
|
if (timerActive)
|
||||||
{
|
{
|
||||||
|
|
@ -1178,7 +1181,7 @@ bool NormObject::AppendRepairRequest(NormNackMsg& nack,
|
||||||
return requestAppended;
|
return requestAppended;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flush || (nextId != max_pending_block))
|
if (flush || (nextId != max_pending_block))
|
||||||
{
|
{
|
||||||
block->AppendRepairRequest(nack, fec_id, fec_m, numData, nparity, transport_id,
|
block->AppendRepairRequest(nack, fec_id, fec_m, numData, nparity, transport_id,
|
||||||
pending_info, segment_size); // (TBD) error check
|
pending_info, segment_size); // (TBD) error check
|
||||||
|
|
@ -1192,10 +1195,10 @@ bool NormObject::AppendRepairRequest(NormNackMsg& nack,
|
||||||
block->AppendRepairRequest(nack, fec_id, fec_m, numData, nparity, transport_id,
|
block->AppendRepairRequest(nack, fec_id, fec_m, numData, nparity, transport_id,
|
||||||
pending_info, segment_size); // (TBD) error check
|
pending_info, segment_size); // (TBD) error check
|
||||||
}
|
}
|
||||||
requestAppended = true;
|
requestAppended = true;
|
||||||
|
prevForm = NormRepairRequest::INVALID;
|
||||||
}
|
}
|
||||||
consecutiveCount = 0;
|
consecutiveCount = 0;
|
||||||
prevForm = NormRepairRequest::INVALID;
|
|
||||||
}
|
}
|
||||||
else if (iterating)
|
else if (iterating)
|
||||||
{
|
{
|
||||||
|
|
@ -2832,7 +2835,7 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
|
||||||
{
|
{
|
||||||
// This is a fresh rx stream, so init the read indices
|
// This is a fresh rx stream, so init the read indices
|
||||||
read_init = false;
|
read_init = false;
|
||||||
read_index.block = blockId;
|
read_index.block = blockId; // for initial SYNC_STREAM sync, this will be zero (stream beginning)
|
||||||
read_index.segment = 0;
|
read_index.segment = 0;
|
||||||
read_offset = 0;
|
read_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3940,6 +3943,7 @@ void NormObjectTable::Destroy()
|
||||||
{
|
{
|
||||||
// TBD - should we issue PURGED/ABORTED notifications here???
|
// TBD - should we issue PURGED/ABORTED notifications here???
|
||||||
// (We haven't since this is destroyed only when session is terminated)
|
// (We haven't since this is destroyed only when session is terminated)
|
||||||
|
// or when a NormSenderNode is deleted
|
||||||
Remove(obj);
|
Remove(obj);
|
||||||
obj->Release();
|
obj->Release();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
|
||||||
: session_mgr(sessionMgr), notify_pending(false), tx_port(0), tx_port_reuse(false),
|
: session_mgr(sessionMgr), notify_pending(false), tx_port(0), tx_port_reuse(false),
|
||||||
tx_socket_actual(ProtoSocket::UDP), tx_socket(&tx_socket_actual),
|
tx_socket_actual(ProtoSocket::UDP), tx_socket(&tx_socket_actual),
|
||||||
rx_socket(ProtoSocket::UDP), rx_cap(NULL), rx_port_reuse(false), local_node_id(localNodeId),
|
rx_socket(ProtoSocket::UDP), rx_cap(NULL), rx_port_reuse(false), local_node_id(localNodeId),
|
||||||
ttl(DEFAULT_TTL), tos(0), loopback(false), fragmentation(false), ecn_enabled(false),
|
ttl(DEFAULT_TTL), tos(0), loopback(false), mcast_loopback(false), fragmentation(false), ecn_enabled(false),
|
||||||
tx_rate(DEFAULT_TRANSMIT_RATE/8.0), tx_rate_min(-1.0), tx_rate_max(-1.0),
|
tx_rate(DEFAULT_TRANSMIT_RATE/8.0), tx_rate_min(-1.0), tx_rate_max(-1.0),
|
||||||
backoff_factor(DEFAULT_BACKOFF_FACTOR), is_sender(false),
|
backoff_factor(DEFAULT_BACKOFF_FACTOR), is_sender(false),
|
||||||
tx_robust_factor(DEFAULT_ROBUST_FACTOR), instance_id(0),
|
tx_robust_factor(DEFAULT_ROBUST_FACTOR), instance_id(0),
|
||||||
|
|
@ -66,8 +66,8 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
|
||||||
user_data(NULL), next(NULL)
|
user_data(NULL), next(NULL)
|
||||||
{
|
{
|
||||||
interface_name[0] = '\0';
|
interface_name[0] = '\0';
|
||||||
tx_socket->SetNotifier(&sessionMgr.GetSocketNotifier());
|
tx_socket_actual.SetNotifier(&sessionMgr.GetSocketNotifier());
|
||||||
tx_socket->SetListener(this, &NormSession::TxSocketRecvHandler);
|
tx_socket_actual.SetListener(this, &NormSession::TxSocketRecvHandler);
|
||||||
tx_address.Invalidate();
|
tx_address.Invalidate();
|
||||||
|
|
||||||
rx_socket.SetNotifier(&sessionMgr.GetSocketNotifier());
|
rx_socket.SetNotifier(&sessionMgr.GetSocketNotifier());
|
||||||
|
|
@ -112,10 +112,15 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
|
||||||
report_timer.SetListener(this, &NormSession::OnReportTimeout);
|
report_timer.SetListener(this, &NormSession::OnReportTimeout);
|
||||||
report_timer.SetInterval(10.0);
|
report_timer.SetInterval(10.0);
|
||||||
report_timer.SetRepeat(-1);
|
report_timer.SetRepeat(-1);
|
||||||
|
|
||||||
|
user_timer.SetListener(this, &NormSession::OnUserTimeout);
|
||||||
|
user_timer.SetInterval(0.0);
|
||||||
|
user_timer.SetRepeat(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NormSession::~NormSession()
|
NormSession::~NormSession()
|
||||||
{
|
{
|
||||||
|
if (user_timer.IsActive()) user_timer.Deactivate();
|
||||||
if (NULL != preset_sender)
|
if (NULL != preset_sender)
|
||||||
{
|
{
|
||||||
delete preset_sender;
|
delete preset_sender;
|
||||||
|
|
@ -170,7 +175,6 @@ bool NormSession::Open()
|
||||||
{
|
{
|
||||||
tx_socket = &rx_socket;
|
tx_socket = &rx_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!rx_socket.IsOpen() && (!tx_only || (&rx_socket == tx_socket)))
|
if (!rx_socket.IsOpen() && (!tx_only || (&rx_socket == tx_socket)))
|
||||||
{
|
{
|
||||||
|
|
@ -180,6 +184,7 @@ bool NormSession::Open()
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
rx_socket.EnableRecvDstAddr();
|
||||||
if (rx_port_reuse)
|
if (rx_port_reuse)
|
||||||
{
|
{
|
||||||
// Enable port/addr reuse and bind socket to destination address
|
// Enable port/addr reuse and bind socket to destination address
|
||||||
|
|
@ -204,7 +209,7 @@ bool NormSession::Open()
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (rx_connect_addr.IsValid())
|
if (rx_connect_addr.IsValid() && (0 != rx_connect_addr.GetPort()))
|
||||||
{
|
{
|
||||||
// For unicast, we use the "connect()" call to effectively
|
// For unicast, we use the "connect()" call to effectively
|
||||||
// uniquely "bind" our rx_socket to the remote addr.
|
// uniquely "bind" our rx_socket to the remote addr.
|
||||||
|
|
@ -243,7 +248,7 @@ bool NormSession::Open()
|
||||||
Close();
|
Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!tx_socket->SetLoopback(loopback))
|
if (!tx_socket->SetLoopback(mcast_loopback))
|
||||||
{
|
{
|
||||||
// TBD - Should this be set on the rx_socket instead???
|
// TBD - Should this be set on the rx_socket instead???
|
||||||
PLOG(PL_FATAL, "NormSession::Open() tx_socket.SetLoopback() error\n");
|
PLOG(PL_FATAL, "NormSession::Open() tx_socket.SetLoopback() error\n");
|
||||||
|
|
@ -265,7 +270,7 @@ bool NormSession::Open()
|
||||||
}
|
}
|
||||||
if (!tx_only)
|
if (!tx_only)
|
||||||
{
|
{
|
||||||
if (!rx_socket.JoinGroup(address, interfaceName))
|
if (!rx_socket.JoinGroup(address, interfaceName, ssm_source_addr.IsValid() ? &ssm_source_addr : NULL))
|
||||||
{
|
{
|
||||||
PLOG(PL_FATAL, "NormSession::Open() rx_socket.JoinGroup error\n");
|
PLOG(PL_FATAL, "NormSession::Open() rx_socket.JoinGroup error\n");
|
||||||
Close();
|
Close();
|
||||||
|
|
@ -371,7 +376,7 @@ void NormSession::Close()
|
||||||
{
|
{
|
||||||
const char* interfaceName = ('\0' != interface_name[0]) ?
|
const char* interfaceName = ('\0' != interface_name[0]) ?
|
||||||
interface_name : NULL;
|
interface_name : NULL;
|
||||||
rx_socket.LeaveGroup(address, interfaceName);
|
rx_socket.LeaveGroup(address, interfaceName, ssm_source_addr.IsValid() ? &ssm_source_addr : NULL);
|
||||||
}
|
}
|
||||||
rx_socket.Close();
|
rx_socket.Close();
|
||||||
}
|
}
|
||||||
|
|
@ -406,6 +411,27 @@ bool NormSession::SetMulticastInterface(const char* interfaceName)
|
||||||
}
|
}
|
||||||
} // end NormSession::SetMulticastInterface()
|
} // end NormSession::SetMulticastInterface()
|
||||||
|
|
||||||
|
bool NormSession::SetSSM(const char* sourceAddress)
|
||||||
|
{
|
||||||
|
if (NULL != sourceAddress)
|
||||||
|
{
|
||||||
|
if (ssm_source_addr.ResolveFromString(sourceAddress))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PLOG(PL_ERROR, "NormSession::SetSSM() error: invalid source address\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssm_source_addr.Invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // end NormSession::SetSSM()
|
||||||
|
|
||||||
bool NormSession::SetRxPortReuse(bool enableReuse,
|
bool NormSession::SetRxPortReuse(bool enableReuse,
|
||||||
const char* rxBindAddress, // bind() to <rxBindAddress>/<sessionPort>
|
const char* rxBindAddress, // bind() to <rxBindAddress>/<sessionPort>
|
||||||
const char* senderAddress, // connect() to <senderAddress>/<senderPort>
|
const char* senderAddress, // connect() to <senderAddress>/<senderPort>
|
||||||
|
|
@ -424,6 +450,7 @@ bool NormSession::SetRxPortReuse(bool enableReuse,
|
||||||
}
|
}
|
||||||
if (NULL != senderAddress)
|
if (NULL != senderAddress)
|
||||||
{
|
{
|
||||||
|
// TBD - if open, connect() to sender?
|
||||||
if (rx_connect_addr.ResolveFromString(senderAddress))
|
if (rx_connect_addr.ResolveFromString(senderAddress))
|
||||||
{
|
{
|
||||||
rx_connect_addr.SetPort(senderPort);
|
rx_connect_addr.SetPort(senderPort);
|
||||||
|
|
@ -491,18 +518,21 @@ void NormSession::SetTxOnly(bool txOnly, bool connectToSessionAddress)
|
||||||
{
|
{
|
||||||
tx_only = txOnly;
|
tx_only = txOnly;
|
||||||
tx_connect = connectToSessionAddress;
|
tx_connect = connectToSessionAddress;
|
||||||
if (txOnly && IsOpen())
|
if (IsOpen())
|
||||||
{
|
{
|
||||||
if (IsReceiver()) StopReceiver();
|
if (txOnly)
|
||||||
if (rx_socket.IsOpen()) rx_socket.Close();
|
|
||||||
#ifdef ECN_SUPPORT
|
|
||||||
if (NULL != rx_cap)
|
|
||||||
{
|
{
|
||||||
rx_cap->Close();
|
if (IsReceiver()) StopReceiver();
|
||||||
delete rx_cap;
|
if (rx_socket.IsOpen()) rx_socket.Close();
|
||||||
rx_cap = NULL;
|
#ifdef ECN_SUPPORT
|
||||||
}
|
if (NULL != rx_cap)
|
||||||
|
{
|
||||||
|
rx_cap->Close();
|
||||||
|
delete rx_cap;
|
||||||
|
rx_cap = NULL;
|
||||||
|
}
|
||||||
#endif // ECN_SUPPORT
|
#endif // ECN_SUPPORT
|
||||||
|
}
|
||||||
// We connect tx_only session sockets when tx port
|
// We connect tx_only session sockets when tx port
|
||||||
// reuse is set _and_ it is a unicast session
|
// reuse is set _and_ it is a unicast session
|
||||||
// (This makes sure unicast NACKs get back to the right tx_socket!)
|
// (This makes sure unicast NACKs get back to the right tx_socket!)
|
||||||
|
|
@ -530,13 +560,14 @@ double NormSession::GetTxRate()
|
||||||
} // end NormSession::GetTxRate()
|
} // end NormSession::GetTxRate()
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// This hack can be uncommented give us a tx rate interval that is POISSON instead of PERIODIC
|
||||||
static double PoissonRand(double mean)
|
static double PoissonRand(double mean)
|
||||||
{
|
{
|
||||||
return(-log(((double)rand())/((double)RAND_MAX))*mean);
|
return(-log(((double)rand())/((double)RAND_MAX))*mean);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// This hack can give us a tx rate interval that is POISSON instead of PERIODIC
|
|
||||||
static inline double GetTxInterval(unsigned int msgSize, double txRate)
|
static inline double GetTxInterval(unsigned int msgSize, double txRate)
|
||||||
{
|
{
|
||||||
double interval = (double)msgSize / txRate;
|
double interval = (double)msgSize / txRate;
|
||||||
|
|
@ -653,6 +684,17 @@ void NormSession::SetTxRateBounds(double rateMin, double rateMax)
|
||||||
} // end NormSession::SetTxRateBounds()
|
} // end NormSession::SetTxRateBounds()
|
||||||
|
|
||||||
|
|
||||||
|
void NormSession::SetUserTimer(double seconds)
|
||||||
|
{
|
||||||
|
if (user_timer.IsActive()) user_timer.Deactivate();
|
||||||
|
if (seconds >= 0.0)
|
||||||
|
{
|
||||||
|
user_timer.SetInterval(seconds);
|
||||||
|
ActivateTimer(user_timer);
|
||||||
|
}
|
||||||
|
} // end NormSession::SetUserTimer()
|
||||||
|
|
||||||
|
|
||||||
bool NormSession::StartSender(UINT16 instanceId,
|
bool NormSession::StartSender(UINT16 instanceId,
|
||||||
UINT32 bufferSpace,
|
UINT32 bufferSpace,
|
||||||
UINT16 segmentSize,
|
UINT16 segmentSize,
|
||||||
|
|
@ -797,7 +839,7 @@ bool NormSession::StartSender(UINT16 instanceId,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Don't let txRate below MIN(one segment per grtt, one segment per seconds)
|
// Don't let txRate below MIN(one segment per grtt, one segment per second)
|
||||||
txRate = ((double)segment_size) / grtt_measured;
|
txRate = ((double)segment_size) / grtt_measured;
|
||||||
if (txRate > ((double)(segment_size)))
|
if (txRate > ((double)(segment_size)))
|
||||||
txRate = (double)(segment_size);
|
txRate = (double)(segment_size);
|
||||||
|
|
@ -898,7 +940,7 @@ void NormSession::StopReceiver()
|
||||||
// Iterate sender_tree and close/release sender nodes
|
// Iterate sender_tree and close/release sender nodes
|
||||||
NormSenderNode* senderNode =
|
NormSenderNode* senderNode =
|
||||||
static_cast<NormSenderNode*>(sender_tree.GetRoot());
|
static_cast<NormSenderNode*>(sender_tree.GetRoot());
|
||||||
while (senderNode)
|
while (NULL != senderNode)
|
||||||
{
|
{
|
||||||
sender_tree.DetachNode(senderNode);
|
sender_tree.DetachNode(senderNode);
|
||||||
senderNode->Close();
|
senderNode->Close();
|
||||||
|
|
@ -916,7 +958,7 @@ void NormSession::DeleteRemoteSender(NormSenderNode& senderNode)
|
||||||
sender_tree.DetachNode(&senderNode);
|
sender_tree.DetachNode(&senderNode);
|
||||||
senderNode.Close();
|
senderNode.Close();
|
||||||
senderNode.Release();
|
senderNode.Release();
|
||||||
} // end NormSession::DeleteSender()
|
} // end NormSession::DeleteRemoteSender()
|
||||||
|
|
||||||
bool NormSession::PreallocateRemoteSender(UINT16 segmentSize,
|
bool NormSession::PreallocateRemoteSender(UINT16 segmentSize,
|
||||||
UINT16 numData,
|
UINT16 numData,
|
||||||
|
|
@ -1153,7 +1195,7 @@ void NormSession::Serve()
|
||||||
{
|
{
|
||||||
SenderQueueFlush();
|
SenderQueueFlush();
|
||||||
}
|
}
|
||||||
else if (GetTxRobustFactor() == flush_count) //xxx
|
else if (GetTxRobustFactor() == flush_count)
|
||||||
{
|
{
|
||||||
|
|
||||||
PLOG(PL_TRACE, "NormSession::Serve() node>%lu sender stream flush complete ...\n",
|
PLOG(PL_TRACE, "NormSession::Serve() node>%lu sender stream flush complete ...\n",
|
||||||
|
|
@ -1270,7 +1312,7 @@ void NormSession::SenderCancelWatermark()
|
||||||
watermark_pending = false;
|
watermark_pending = false;
|
||||||
} // end NormSession::SenderCancelWatermark()
|
} // end NormSession::SenderCancelWatermark()
|
||||||
|
|
||||||
bool NormSession::SenderAddAckingNode(NormNodeId nodeId)
|
NormAckingNode* NormSession::SenderAddAckingNode(NormNodeId nodeId, const ProtoAddress* srcAddress)
|
||||||
{
|
{
|
||||||
NormAckingNode* theNode = static_cast<NormAckingNode*>(acking_node_tree.FindNodeById(nodeId));
|
NormAckingNode* theNode = static_cast<NormAckingNode*>(acking_node_tree.FindNodeById(nodeId));
|
||||||
if (NULL == theNode)
|
if (NULL == theNode)
|
||||||
|
|
@ -1281,18 +1323,19 @@ bool NormSession::SenderAddAckingNode(NormNodeId nodeId)
|
||||||
theNode->Reset(GetTxRobustFactor());
|
theNode->Reset(GetTxRobustFactor());
|
||||||
acking_node_tree.AttachNode(theNode);
|
acking_node_tree.AttachNode(theNode);
|
||||||
acking_node_count++;
|
acking_node_count++;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormSession::SenderAddAckingNode() new NormAckingNode error: %s\n", GetErrorString());
|
PLOG(PL_ERROR, "NormSession::SenderAddAckingNode() new NormAckingNode error: %s\n", GetErrorString());
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormSession::SenderAddAckingNode() warning: node already in list!?\n");
|
PLOG(PL_WARN, "NormSession::SenderAddAckingNode() warning: node already in list!?\n");
|
||||||
}
|
}
|
||||||
return true;
|
if (NULL != srcAddress) theNode->SetAddress(*srcAddress);
|
||||||
|
return theNode;
|
||||||
} // end NormSession::AddAckingNode(NormNodeId nodeId)
|
} // end NormSession::AddAckingNode(NormNodeId nodeId)
|
||||||
|
|
||||||
void NormSession::SenderRemoveAckingNode(NormNodeId nodeId)
|
void NormSession::SenderRemoveAckingNode(NormNodeId nodeId)
|
||||||
|
|
@ -1967,33 +2010,45 @@ char* NormSession::SenderGetFreeSegment(NormObjectId objectId,
|
||||||
return segment_pool.Get();
|
return segment_pool.Get();
|
||||||
} // end NormSession::SenderGetFreeSegment()
|
} // end NormSession::SenderGetFreeSegment()
|
||||||
|
|
||||||
void NormSession::TxSocketRecvHandler(ProtoSocket& /*theSocket*/,
|
void NormSession::TxSocketRecvHandler(ProtoSocket& theSocket,
|
||||||
ProtoSocket::Event theEvent)
|
ProtoSocket::Event theEvent)
|
||||||
{
|
{
|
||||||
if (ProtoSocket::RECV == theEvent)
|
if (ProtoSocket::RECV == theEvent)
|
||||||
{
|
{
|
||||||
NormMsg msg;
|
NormMsg msg;
|
||||||
unsigned int msgLength = NormMsg::MAX_SIZE;
|
unsigned int msgLength = NormMsg::MAX_SIZE;
|
||||||
while (tx_socket->RecvFrom(msg.AccessBuffer(),
|
while (true)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (theSocket.RecvFrom(msg.AccessBuffer(),
|
||||||
msgLength,
|
msgLength,
|
||||||
msg.AccessAddress()))
|
msg.AccessAddress()))
|
||||||
{
|
|
||||||
if (0 == msgLength) break; // no more data to read
|
|
||||||
if (msg.InitFromBuffer(msgLength))
|
|
||||||
{
|
{
|
||||||
HandleReceiveMessage(msg, true);
|
if (0 == msgLength) break; // no more data to read
|
||||||
msgLength = NormMsg::MAX_SIZE;
|
if (msg.InitFromBuffer(msgLength))
|
||||||
|
{
|
||||||
|
// Since it arrived on the tx_socket, we know it was unicast
|
||||||
|
HandleReceiveMessage(msg, true);
|
||||||
|
msgLength = NormMsg::MAX_SIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PLOG(PL_ERROR, "NormSession::TxSocketRecvHandler() warning: received bad message\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormSession::TxSocketRecvHandler() warning: received bad message\n");
|
// Probably an ICMP "port unreachable" error
|
||||||
|
if (Address().IsUnicast())
|
||||||
|
Notify(NormController::SEND_ERROR, NULL, NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ProtoSocket::SEND == theEvent)
|
else if (ProtoSocket::SEND == theEvent)
|
||||||
{
|
{
|
||||||
// This is a little cheesy, but ...
|
// This is a little cheesy, but ...
|
||||||
tx_socket->StopOutputNotification();
|
theSocket.StopOutputNotification();
|
||||||
if (tx_timer.IsActive()) tx_timer.Deactivate();
|
if (tx_timer.IsActive()) tx_timer.Deactivate();
|
||||||
if (OnTxTimeout(tx_timer))
|
if (OnTxTimeout(tx_timer))
|
||||||
{
|
{
|
||||||
|
|
@ -2014,80 +2069,110 @@ int rxMeasureGapMax = 0;
|
||||||
#endif // RX_MEASURE_ONLY
|
#endif // RX_MEASURE_ONLY
|
||||||
|
|
||||||
void NormSession::RxSocketRecvHandler(ProtoSocket& theSocket,
|
void NormSession::RxSocketRecvHandler(ProtoSocket& theSocket,
|
||||||
ProtoSocket::Event /*theEvent*/)
|
ProtoSocket::Event theEvent)
|
||||||
{
|
{
|
||||||
unsigned int recvCount = 0;
|
if (ProtoSocket::RECV == theEvent)
|
||||||
NormMsg msg;
|
|
||||||
unsigned int msgLength = NormMsg::MAX_SIZE;
|
|
||||||
while (theSocket.RecvFrom(msg.AccessBuffer(),
|
|
||||||
msgLength,
|
|
||||||
msg.AccessAddress()))
|
|
||||||
{
|
{
|
||||||
if (0 == msgLength) break;
|
unsigned int recvCount = 0;
|
||||||
if (msg.InitFromBuffer(msgLength))
|
NormMsg msg;
|
||||||
|
unsigned int msgLength = NormMsg::MAX_SIZE;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
|
ProtoAddress destAddr; // we get the pkt destAddr to determine unicast/multicast
|
||||||
|
if (theSocket.RecvFrom(msg.AccessBuffer(),
|
||||||
|
msgLength,
|
||||||
|
msg.AccessAddress(),
|
||||||
|
destAddr))
|
||||||
|
{
|
||||||
|
if (0 == msgLength) break;
|
||||||
|
if (msg.InitFromBuffer(msgLength))
|
||||||
|
{
|
||||||
#ifdef RX_MEASURE_ONLY
|
#ifdef RX_MEASURE_ONLY
|
||||||
// Measure rx rate / loss stats only
|
// Measure rx rate / loss stats only
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
ProtoSystemTime(currentTime);
|
ProtoSystemTime(currentTime);
|
||||||
UINT16 seq = msg.GetSequence();
|
UINT16 seq = msg.GetSequence();
|
||||||
if (rxMeasureInit)
|
if (rxMeasureInit)
|
||||||
{
|
{
|
||||||
rxMeasureRefTime = currentTime;
|
rxMeasureRefTime = currentTime;
|
||||||
rxMeasureSeqPrev = seq;
|
rxMeasureSeqPrev = seq;
|
||||||
rxMeasurePktCount = rxMeasurePktTotal = 1;
|
rxMeasurePktCount = rxMeasurePktTotal = 1;
|
||||||
rxMeasureByteTotal = msgLength;
|
rxMeasureByteTotal = msgLength;
|
||||||
rxMeasureInit = false;
|
rxMeasureInit = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int seqDelta = (int)seq - (int)rxMeasureSeqPrev;
|
int seqDelta = (int)seq - (int)rxMeasureSeqPrev;
|
||||||
ASSERT(seqDelta > 0);
|
ASSERT(seqDelta > 0);
|
||||||
|
|
||||||
rxMeasurePktTotal += seqDelta; // total should have received.
|
rxMeasurePktTotal += seqDelta; // total should have received.
|
||||||
rxMeasurePktCount++; // total actually received
|
rxMeasurePktCount++; // total actually received
|
||||||
rxMeasureByteTotal += msgLength;
|
rxMeasureByteTotal += msgLength;
|
||||||
|
|
||||||
if (seqDelta > rxMeasureGapMax)
|
if (seqDelta > rxMeasureGapMax)
|
||||||
rxMeasureGapMax = seqDelta;
|
rxMeasureGapMax = seqDelta;
|
||||||
|
|
||||||
int deltaSec = currentTime.tv_sec - rxMeasureRefTime.tv_sec;
|
int deltaSec = currentTime.tv_sec - rxMeasureRefTime.tv_sec;
|
||||||
if (deltaSec >= 10)
|
if (deltaSec >= 10)
|
||||||
{
|
{
|
||||||
if (currentTime.tv_usec > rxMeasureRefTime.tv_usec)
|
if (currentTime.tv_usec > rxMeasureRefTime.tv_usec)
|
||||||
deltaSec += 1.0e-06 * (double)(currentTime.tv_usec - rxMeasureRefTime.tv_usec);
|
deltaSec += 1.0e-06 * (double)(currentTime.tv_usec - rxMeasureRefTime.tv_usec);
|
||||||
else
|
else
|
||||||
deltaSec -= 1.0e-06 * (double)(rxMeasureRefTime.tv_usec - currentTime.tv_usec);
|
deltaSec -= 1.0e-06 * (double)(rxMeasureRefTime.tv_usec - currentTime.tv_usec);
|
||||||
double rxRate = (8.0/1000.0) * (double)rxMeasureByteTotal / (double)deltaSec;
|
double rxRate = (8.0/1000.0) * (double)rxMeasureByteTotal / (double)deltaSec;
|
||||||
double rxLoss = 100.0 * (1.0 - (double)rxMeasurePktCount / (double)rxMeasurePktTotal);
|
double rxLoss = 100.0 * (1.0 - (double)rxMeasurePktCount / (double)rxMeasurePktTotal);
|
||||||
|
|
||||||
rxMeasureRefTime = currentTime;
|
rxMeasureRefTime = currentTime;
|
||||||
rxMeasureByteTotal = rxMeasurePktCount = rxMeasurePktTotal = rxMeasureGapMax = 0;
|
rxMeasureByteTotal = rxMeasurePktCount = rxMeasurePktTotal = rxMeasureGapMax = 0;
|
||||||
}
|
}
|
||||||
rxMeasureSeqPrev = seq;
|
rxMeasureSeqPrev = seq;
|
||||||
return;
|
return;
|
||||||
#endif // RX_MEASURE_ONLY
|
#endif // RX_MEASURE_ONLY
|
||||||
bool ecnStatus = false;
|
bool ecnStatus = false;
|
||||||
#ifdef SIMULATE
|
#ifdef SIMULATE
|
||||||
ecnStatus = theSocket.GetEcnStatus();
|
ecnStatus = theSocket.GetEcnStatus();
|
||||||
//if (ecnStatus) TRACE("NORM RECEIVED PACKET W/ ECN BIT SET!!!!!\n");
|
//if (ecnStatus) TRACE("NORM RECEIVED PACKET W/ ECN BIT SET!!!!!\n");
|
||||||
#endif // SIMULATE
|
#endif // SIMULATE
|
||||||
HandleReceiveMessage(msg, false, ecnStatus);
|
bool wasUnicast;
|
||||||
msgLength = NormMsg::MAX_SIZE;
|
if (destAddr.IsValid())
|
||||||
}
|
wasUnicast = destAddr.IsUnicast();
|
||||||
else
|
else
|
||||||
{
|
wasUnicast = false;
|
||||||
PLOG(PL_ERROR, "NormSession::RxSocketRecvHandler() warning: received bad message\n");
|
HandleReceiveMessage(msg, wasUnicast, ecnStatus);
|
||||||
}
|
msgLength = NormMsg::MAX_SIZE;
|
||||||
// If our system gets very busy reading sockets, we should occasionally
|
}
|
||||||
// execute any timeouts to keep protocol operation smooth (i.e., sending feedback)
|
else
|
||||||
// TBD - perhaps this should be time based
|
{
|
||||||
if (++recvCount >= 100)
|
PLOG(PL_ERROR, "NormSession::RxSocketRecvHandler() warning: received bad message\n");
|
||||||
{
|
}
|
||||||
break;
|
// If our system gets very busy reading sockets, we should occasionally
|
||||||
//session_mgr.DoSystemTimeout();
|
// execute any timeouts to keep protocol operation smooth (i.e., sending feedback)
|
||||||
//recvCount = 0;
|
// TBD - perhaps this should be time based
|
||||||
|
if (++recvCount >= 100)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
//session_mgr.DoSystemTimeout();
|
||||||
|
//recvCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Probably an ICMP "port unreachable" error
|
||||||
|
if (Address().IsUnicast())
|
||||||
|
Notify(NormController::SEND_ERROR, NULL, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ProtoSocket::SEND == theEvent)
|
||||||
|
{
|
||||||
|
// This is a little cheesy, but ...
|
||||||
|
theSocket.StopOutputNotification();
|
||||||
|
if (tx_timer.IsActive()) tx_timer.Deactivate();
|
||||||
|
if (OnTxTimeout(tx_timer))
|
||||||
|
{
|
||||||
|
if (!tx_timer.IsActive()) ActivateTimer(tx_timer);
|
||||||
|
}
|
||||||
|
} // end if/else (theEvent == RECV/SEND)
|
||||||
} // end NormSession::RxSocketRecvHandler()
|
} // end NormSession::RxSocketRecvHandler()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2176,8 +2261,24 @@ void NormSession::OnPktCapture(ProtoChannel& theChannel,
|
||||||
continue; // not a UDP packet for our session, go read next packet
|
continue; // not a UDP packet for our session, go read next packet
|
||||||
// If our rx_socket is "connected", make sure source addr/port matches
|
// If our rx_socket is "connected", make sure source addr/port matches
|
||||||
srcIp.SetPort(udpPkt.GetSrcPort());
|
srcIp.SetPort(udpPkt.GetSrcPort());
|
||||||
if (rx_connect_addr.IsValid() && !rx_connect_addr.IsEqual(srcIp))
|
// if socket is connected, validate that the packet's from the specified source addr
|
||||||
continue; // not from the remote tx_socket to which we are "connected"
|
if (rx_connect_addr.IsValid())
|
||||||
|
{
|
||||||
|
if (0 != rx_connect_addr.GetPort())
|
||||||
|
{
|
||||||
|
// check host addr component only for match
|
||||||
|
if (!rx_connect_addr.HostIsEqual(srcIp)) continue;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check for addr _and_ port match
|
||||||
|
if (!rx_connect_addr.IsEqual(srcIp)) continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we are using SSM multicast make sure it's the right source addr
|
||||||
|
if (ssm_source_addr.IsValid() && !ssm_source_addr.HostIsEqual(srcIp)) continue;
|
||||||
|
|
||||||
// IMPORTANT NOTE: We ignore the checksum for OUTBOUND packets since these
|
// IMPORTANT NOTE: We ignore the checksum for OUTBOUND packets since these
|
||||||
// are often computed by the Ethernet hardware these days
|
// are often computed by the Ethernet hardware these days
|
||||||
|
|
@ -2194,7 +2295,7 @@ void NormSession::OnPktCapture(ProtoChannel& theChannel,
|
||||||
{
|
{
|
||||||
|
|
||||||
msg.AccessAddress() = srcIp;
|
msg.AccessAddress() = srcIp;
|
||||||
HandleReceiveMessage(msg, !dstIp.IsMulticast(), (ProtoSocket::ECN_CE == ecnStatus));
|
HandleReceiveMessage(msg, dstIp.IsUnicast(), (ProtoSocket::ECN_CE == ecnStatus));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2209,7 +2310,8 @@ void NormTrace(const struct timeval& currentTime,
|
||||||
NormNodeId localId,
|
NormNodeId localId,
|
||||||
const NormMsg& msg,
|
const NormMsg& msg,
|
||||||
bool sent,
|
bool sent,
|
||||||
UINT8 fecM)
|
UINT8 fecM,
|
||||||
|
UINT16 instId)
|
||||||
{
|
{
|
||||||
static const char* MSG_NAME[] =
|
static const char* MSG_NAME[] =
|
||||||
{
|
{
|
||||||
|
|
@ -2270,7 +2372,7 @@ void NormTrace(const struct timeval& currentTime,
|
||||||
{
|
{
|
||||||
const NormInfoMsg& info = (const NormInfoMsg&)msg;
|
const NormInfoMsg& info = (const NormInfoMsg&)msg;
|
||||||
PLOG(PL_ALWAYS, "inst>%hu seq>%hu INFO obj>%hu ",
|
PLOG(PL_ALWAYS, "inst>%hu seq>%hu INFO obj>%hu ",
|
||||||
info.GetInstanceId(), seq, (UINT16)info.GetObjectId());
|
info.GetInstanceId(), seq, (UINT16)info.GetObjectId());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NormMsg::DATA:
|
case NormMsg::DATA:
|
||||||
|
|
@ -2367,6 +2469,7 @@ void NormTrace(const struct timeval& currentTime,
|
||||||
case NormMsg::ACK:
|
case NormMsg::ACK:
|
||||||
case NormMsg::NACK:
|
case NormMsg::NACK:
|
||||||
{
|
{
|
||||||
|
PLOG(PL_ALWAYS, "inst>%hu ", instId);
|
||||||
// look for NormCCFeedback extension
|
// look for NormCCFeedback extension
|
||||||
NormHeaderExtension ext;
|
NormHeaderExtension ext;
|
||||||
while (msg.GetNextExtension(ext))
|
while (msg.GetNextExtension(ext))
|
||||||
|
|
@ -2394,7 +2497,7 @@ void NormTrace(const struct timeval& currentTime,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_ALWAYS, "ACK(XXX) ");
|
PLOG(PL_ALWAYS, "ACK(ZZZ) ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2425,7 +2528,42 @@ void NormSession::HandleReceiveMessage(NormMsg& msg, bool wasUnicast, bool ecnSt
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
::ProtoSystemTime(currentTime);
|
::ProtoSystemTime(currentTime);
|
||||||
|
|
||||||
if (trace) NormTrace(currentTime, LocalNodeId(), msg, false, 16); // TBD don't assume m == 16 (i.e. for fec_id == 2)
|
if (trace)
|
||||||
|
{
|
||||||
|
// Initially assume it's a message we generated (or similarly configured sender)
|
||||||
|
UINT8 fecM = fec_m;
|
||||||
|
UINT16 instId = instance_id;
|
||||||
|
NormNodeId senderId;
|
||||||
|
switch (msg.GetType())
|
||||||
|
{
|
||||||
|
case NormMsg::ACK:
|
||||||
|
senderId = static_cast<NormAckMsg&>(msg).GetSenderId();
|
||||||
|
break;
|
||||||
|
case NormMsg::NACK:
|
||||||
|
senderId = static_cast<NormAckMsg&>(msg).GetSenderId();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
senderId = msg.GetSourceId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IsReceiver() && (senderId != LocalNodeId()))
|
||||||
|
{
|
||||||
|
// Use our receiver state to look up sender if possible
|
||||||
|
NormSenderNode* sender = static_cast<NormSenderNode*>(sender_tree.FindNodeById(senderId));
|
||||||
|
if (NULL != sender)
|
||||||
|
{
|
||||||
|
fecM = sender->GetFecFieldSize();
|
||||||
|
instId = sender->GetInstanceId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fecM = 16; // reasonable assumption
|
||||||
|
instId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NormTrace(currentTime, LocalNodeId(), msg, false, fecM, instId); // TBD don't assume m == 16 (i.e. for fec_id == 2)
|
||||||
|
}
|
||||||
|
|
||||||
NormMsg::Type msgType = msg.GetType();
|
NormMsg::Type msgType = msg.GetType();
|
||||||
|
|
||||||
|
|
@ -2454,6 +2592,8 @@ void NormSession::HandleReceiveMessage(NormMsg& msg, bool wasUnicast, bool ecnSt
|
||||||
{
|
{
|
||||||
if (!SenderAddAckingNode(msg.GetSourceId()))
|
if (!SenderAddAckingNode(msg.GetSourceId()))
|
||||||
PLOG(PL_ERROR, "NormSession::HandleReceiveMessage() error: unable to add acking node!\n");
|
PLOG(PL_ERROR, "NormSession::HandleReceiveMessage() error: unable to add acking node!\n");
|
||||||
|
NormAckingNode* acker = (NormAckingNode*)acking_node_tree.FindNodeById(sourceId);
|
||||||
|
Notify(NormController::ACKING_NODE_NEW, acker, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2513,6 +2653,7 @@ void NormSession::ReceiverHandleObjectMessage(const struct timeval& currentTim
|
||||||
PLOG(PL_INFO, "NormSession::ReceiverHandleObjectMessage() node>%lu sender>%lu instanceId change - resyncing.\n",
|
PLOG(PL_INFO, "NormSession::ReceiverHandleObjectMessage() node>%lu sender>%lu instanceId change - resyncing.\n",
|
||||||
LocalNodeId(), theSender->GetId());
|
LocalNodeId(), theSender->GetId());
|
||||||
theSender->Close();
|
theSender->Close();
|
||||||
|
Notify(NormController::REMOTE_SENDER_RESET, theSender, NULL);
|
||||||
if (!theSender->Open(msg.GetInstanceId()))
|
if (!theSender->Open(msg.GetInstanceId()))
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormSession::ReceiverHandleObjectMessage() node>%lu error re-opening NormSenderNode\n");
|
PLOG(PL_ERROR, "NormSession::ReceiverHandleObjectMessage() node>%lu error re-opening NormSenderNode\n");
|
||||||
|
|
@ -2528,6 +2669,7 @@ void NormSession::ReceiverHandleObjectMessage(const struct timeval& currentTim
|
||||||
theSender = preset_sender;
|
theSender = preset_sender;
|
||||||
preset_sender = NULL;
|
preset_sender = NULL;
|
||||||
theSender->SetId(msg.GetSourceId());
|
theSender->SetId(msg.GetSourceId());
|
||||||
|
theSender->SetAddress(msg.GetSource());
|
||||||
theSender->SetInstanceId(msg.GetInstanceId());
|
theSender->SetInstanceId(msg.GetInstanceId());
|
||||||
sender_tree.AttachNode(theSender);
|
sender_tree.AttachNode(theSender);
|
||||||
PLOG(PL_DEBUG, "NormSession::ReceiverHandleObjectMessage() node>%lu new remote sender:%lu ...\n",
|
PLOG(PL_DEBUG, "NormSession::ReceiverHandleObjectMessage() node>%lu new remote sender:%lu ...\n",
|
||||||
|
|
@ -2535,6 +2677,7 @@ void NormSession::ReceiverHandleObjectMessage(const struct timeval& currentTim
|
||||||
}
|
}
|
||||||
else if (NULL != (theSender = new NormSenderNode(*this, msg.GetSourceId())))
|
else if (NULL != (theSender = new NormSenderNode(*this, msg.GetSourceId())))
|
||||||
{
|
{
|
||||||
|
theSender->SetAddress(msg.GetSource());
|
||||||
Notify(NormController::REMOTE_SENDER_NEW, theSender, NULL);
|
Notify(NormController::REMOTE_SENDER_NEW, theSender, NULL);
|
||||||
if (theSender->Open(msg.GetInstanceId()))
|
if (theSender->Open(msg.GetInstanceId()))
|
||||||
{
|
{
|
||||||
|
|
@ -2558,7 +2701,12 @@ void NormSession::ReceiverHandleObjectMessage(const struct timeval& currentTim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
theSender->Activate(true);
|
theSender->Activate(true);
|
||||||
theSender->SetAddress(msg.GetSource());
|
if (!theSender->GetAddress().IsEqual(msg.GetSource()))
|
||||||
|
{
|
||||||
|
// sender source address has changed
|
||||||
|
theSender->SetAddress(msg.GetSource());
|
||||||
|
Notify(NormController::REMOTE_SENDER_ADDRESS, theSender, NULL);
|
||||||
|
}
|
||||||
theSender->UpdateRecvRate(currentTime, msg.GetLength());
|
theSender->UpdateRecvRate(currentTime, msg.GetLength());
|
||||||
//if (ecnStatus) TRACE("UPDATING LOSS EST w/ ECN pkt\n");
|
//if (ecnStatus) TRACE("UPDATING LOSS EST w/ ECN pkt\n");
|
||||||
theSender->UpdateLossEstimate(currentTime, msg.GetSequence(), ecnStatus);
|
theSender->UpdateLossEstimate(currentTime, msg.GetSequence(), ecnStatus);
|
||||||
|
|
@ -2576,13 +2724,14 @@ void NormSession::ReceiverHandleCommand(const struct timeval& currentTime,
|
||||||
// Do common updates for senders we already know.
|
// Do common updates for senders we already know.
|
||||||
NormNodeId sourceId = cmd.GetSourceId();
|
NormNodeId sourceId = cmd.GetSourceId();
|
||||||
NormSenderNode* theSender = (NormSenderNode*)sender_tree.FindNodeById(sourceId);
|
NormSenderNode* theSender = (NormSenderNode*)sender_tree.FindNodeById(sourceId);
|
||||||
if (theSender)
|
if (NULL != theSender)
|
||||||
{
|
{
|
||||||
if (cmd.GetInstanceId() != theSender->GetInstanceId())
|
if (cmd.GetInstanceId() != theSender->GetInstanceId())
|
||||||
{
|
{
|
||||||
PLOG(PL_INFO, "NormSession::ReceiverHandleCommand() node>%lu sender>%lu instanceId change - resyncing.\n",
|
PLOG(PL_INFO, "NormSession::ReceiverHandleCommand() node>%lu sender>%lu instanceId change - resyncing.\n",
|
||||||
LocalNodeId(), theSender->GetId());
|
LocalNodeId(), theSender->GetId());
|
||||||
theSender->Close();
|
theSender->Close();
|
||||||
|
Notify(NormController::REMOTE_SENDER_RESET, theSender, NULL);
|
||||||
if (!theSender->Open(cmd.GetInstanceId()))
|
if (!theSender->Open(cmd.GetInstanceId()))
|
||||||
{
|
{
|
||||||
PLOG(PL_ERROR, "NormSession::ReceiverHandleCommand() node>%lu error re-opening NormSenderNode\n");
|
PLOG(PL_ERROR, "NormSession::ReceiverHandleCommand() node>%lu error re-opening NormSenderNode\n");
|
||||||
|
|
@ -2600,6 +2749,7 @@ void NormSession::ReceiverHandleCommand(const struct timeval& currentTime,
|
||||||
theSender = preset_sender;
|
theSender = preset_sender;
|
||||||
preset_sender = NULL;
|
preset_sender = NULL;
|
||||||
theSender->SetId(cmd.GetSourceId());
|
theSender->SetId(cmd.GetSourceId());
|
||||||
|
theSender->SetAddress(cmd.GetSource());
|
||||||
theSender->SetInstanceId(cmd.GetInstanceId());
|
theSender->SetInstanceId(cmd.GetInstanceId());
|
||||||
sender_tree.AttachNode(theSender);
|
sender_tree.AttachNode(theSender);
|
||||||
PLOG(PL_DEBUG, "NormSession::ReceiverHandleObjectMessage() node>%lu new remote sender:%lu ...\n",
|
PLOG(PL_DEBUG, "NormSession::ReceiverHandleObjectMessage() node>%lu new remote sender:%lu ...\n",
|
||||||
|
|
@ -2608,6 +2758,7 @@ void NormSession::ReceiverHandleCommand(const struct timeval& currentTime,
|
||||||
else if ((theSender = new NormSenderNode(*this, cmd.GetSourceId())))
|
else if ((theSender = new NormSenderNode(*this, cmd.GetSourceId())))
|
||||||
{
|
{
|
||||||
Notify(NormController::REMOTE_SENDER_NEW, theSender, NULL);
|
Notify(NormController::REMOTE_SENDER_NEW, theSender, NULL);
|
||||||
|
theSender->SetAddress(cmd.GetSource());
|
||||||
if (theSender->Open(cmd.GetInstanceId()))
|
if (theSender->Open(cmd.GetInstanceId()))
|
||||||
{
|
{
|
||||||
sender_tree.AttachNode(theSender);
|
sender_tree.AttachNode(theSender);
|
||||||
|
|
@ -2634,7 +2785,12 @@ void NormSession::ReceiverHandleCommand(const struct timeval& currentTime,
|
||||||
theSender->Activate(true);
|
theSender->Activate(true);
|
||||||
else
|
else
|
||||||
theSender->Activate(false);
|
theSender->Activate(false);
|
||||||
theSender->SetAddress(cmd.GetSource());
|
if (!theSender->GetAddress().IsEqual(cmd.GetSource()))
|
||||||
|
{
|
||||||
|
// sender source address has changed
|
||||||
|
theSender->SetAddress(cmd.GetSource());
|
||||||
|
Notify(NormController::REMOTE_SENDER_ADDRESS, theSender, NULL);
|
||||||
|
}
|
||||||
theSender->UpdateRecvRate(currentTime, cmd.GetLength());
|
theSender->UpdateRecvRate(currentTime, cmd.GetLength());
|
||||||
theSender->UpdateLossEstimate(currentTime, cmd.GetSequence(), ecnStatus);
|
theSender->UpdateLossEstimate(currentTime, cmd.GetSequence(), ecnStatus);
|
||||||
theSender->IncrementRecvTotal(cmd.GetLength()); // for statistics only (TBD) #ifdef NORM_DEBUG
|
theSender->IncrementRecvTotal(cmd.GetLength()); // for statistics only (TBD) #ifdef NORM_DEBUG
|
||||||
|
|
@ -3076,14 +3232,14 @@ void NormSession::SenderHandleNackMessage(const struct timeval& currentTime, Nor
|
||||||
|
|
||||||
if (GetDebugLevel() >= PL_DEBUG)
|
if (GetDebugLevel() >= PL_DEBUG)
|
||||||
{
|
{
|
||||||
PLOG(PL_ALWAYS, "node>%lu sender (tactive:%d)received NACK message with content:\n",
|
PLOG(PL_ALWAYS, "node>%lu sender (tactive:%d) received NACK message with content:\n",
|
||||||
LocalNodeId(), repair_timer.IsActive());
|
LocalNodeId(), repair_timer.IsActive());
|
||||||
LogRepairContent(nack.GetRepairContent(), nack.GetRepairContentLength(), fec_id, fec_m);
|
LogRepairContent(nack.GetRepairContent(), nack.GetRepairContentLength(), fec_id, fec_m);
|
||||||
PLOG(PL_ALWAYS, "\n");
|
PLOG(PL_ALWAYS, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// (TBD) maintain average of "numErasures" for SEGMENT repair requests
|
// (TBD) maintain average of "numErasures" for SEGMENT repair requests
|
||||||
// to use as input to a an automatic "auto parity" adjustor
|
// to use as input to a future automatic "auto parity" adjustor???
|
||||||
// Update GRTT estimate
|
// Update GRTT estimate
|
||||||
struct timeval grttResponse;
|
struct timeval grttResponse;
|
||||||
nack.GetGrttResponse(grttResponse);
|
nack.GetGrttResponse(grttResponse);
|
||||||
|
|
@ -3660,8 +3816,8 @@ void NormSession::ReceiverHandleAckMessage(const NormAckMsg& ack)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_DEBUG, "NormSession::ReceiverHandleAckMessage() node>%lu heard ACK for unknown sender.\n",
|
PLOG(PL_DEBUG, "NormSession::ReceiverHandleAckMessage() node>%lu heard ACK for unknown sender>%lu.\n",
|
||||||
LocalNodeId());
|
LocalNodeId(), ack.GetSenderId());
|
||||||
}
|
}
|
||||||
} // end NormSession::ReceiverHandleAckMessage()
|
} // end NormSession::ReceiverHandleAckMessage()
|
||||||
|
|
||||||
|
|
@ -4239,16 +4395,17 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
// (TBD) fill in InstanceId fields on all messages as needed
|
// (TBD) fill in InstanceId fields on all messages as needed
|
||||||
// We need "fec_m" for the message for NormTrace() purposes
|
// We need "fec_m" for the message for NormTrace() purposes
|
||||||
UINT8 fecM = fec_m; // assume it's a sender message (will be overridden otherwise)
|
UINT8 fecM = fec_m; // assume it's a sender message (will be overridden otherwise)
|
||||||
|
UINT16 instId = instance_id; // assume it's a sender message (will be overridden otherwise)
|
||||||
switch (msg.GetType())
|
switch (msg.GetType())
|
||||||
{
|
{
|
||||||
case NormMsg::INFO:
|
case NormMsg::INFO:
|
||||||
case NormMsg::DATA:
|
case NormMsg::DATA:
|
||||||
((NormObjectMsg&)msg).SetInstanceId(instance_id);
|
((NormObjectMsg&)msg).SetInstanceId(instId);
|
||||||
msg.SetSequence(tx_sequence++); // (TBD) set for session dst msgs
|
msg.SetSequence(tx_sequence++); // (TBD) set for session dst msgs
|
||||||
break;
|
break;
|
||||||
case NormMsg::CMD:
|
case NormMsg::CMD:
|
||||||
{
|
{
|
||||||
((NormCmdMsg&)msg).SetInstanceId(instance_id);
|
((NormCmdMsg&)msg).SetInstanceId(instId);
|
||||||
switch (((NormCmdMsg&)msg).GetFlavor())
|
switch (((NormCmdMsg&)msg).GetFlavor())
|
||||||
{
|
{
|
||||||
case NormCmdMsg::CC:
|
case NormCmdMsg::CC:
|
||||||
|
|
@ -4276,6 +4433,7 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
(NormSenderNode*)sender_tree.FindNodeById(nack.GetSenderId());
|
(NormSenderNode*)sender_tree.FindNodeById(nack.GetSenderId());
|
||||||
ASSERT(NULL != theSender);
|
ASSERT(NULL != theSender);
|
||||||
fecM = theSender->GetFecFieldSize();
|
fecM = theSender->GetFecFieldSize();
|
||||||
|
instId = theSender->GetInstanceId();
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
ProtoSystemTime(currentTime);
|
ProtoSystemTime(currentTime);
|
||||||
struct timeval grttResponse;
|
struct timeval grttResponse;
|
||||||
|
|
@ -4292,6 +4450,7 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
(NormSenderNode*)sender_tree.FindNodeById(ack.GetSenderId());
|
(NormSenderNode*)sender_tree.FindNodeById(ack.GetSenderId());
|
||||||
ASSERT(NULL != theSender);
|
ASSERT(NULL != theSender);
|
||||||
fecM = theSender->GetFecFieldSize();
|
fecM = theSender->GetFecFieldSize();
|
||||||
|
instId = theSender->GetInstanceId();
|
||||||
struct timeval grttResponse;
|
struct timeval grttResponse;
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
ProtoSystemTime(currentTime);
|
ProtoSystemTime(currentTime);
|
||||||
|
|
@ -4325,7 +4484,7 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
{
|
{
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
ProtoSystemTime(currentTime);
|
ProtoSystemTime(currentTime);
|
||||||
NormTrace(currentTime, LocalNodeId(), msg, true, fecM);
|
NormTrace(currentTime, LocalNodeId(), msg, true, fecM, instId);
|
||||||
}
|
}
|
||||||
// Update sent rate tracker even if dropped (for testing/debugging)
|
// Update sent rate tracker even if dropped (for testing/debugging)
|
||||||
sent_accumulator.Increment(msgSize);
|
sent_accumulator.Increment(msgSize);
|
||||||
|
|
@ -4340,7 +4499,7 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
{
|
{
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
ProtoSystemTime(currentTime);
|
ProtoSystemTime(currentTime);
|
||||||
NormTrace(currentTime, LocalNodeId(), msg, true, fecM);
|
NormTrace(currentTime, LocalNodeId(), msg, true, fecM, instId);
|
||||||
}
|
}
|
||||||
// To keep track of _actual_ sent rate
|
// To keep track of _actual_ sent rate
|
||||||
sent_accumulator.Increment(msgSize);
|
sent_accumulator.Increment(msgSize);
|
||||||
|
|
@ -4349,7 +4508,8 @@ bool NormSession::SendMessage(NormMsg& msg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLOG(PL_DETAIL, "NormSession::SendMessage() sendto() error: %s\n", GetErrorString());
|
PLOG(PL_ERROR, "NormSession::SendMessage() sendto(%s/%hu) error: %s\n",
|
||||||
|
msg.GetDestination().GetHostString(), msg.GetDestination().GetPort(), GetErrorString());
|
||||||
tx_sequence--;
|
tx_sequence--;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -4876,10 +5036,19 @@ bool NormSession::OnReportTimeout(ProtoTimer& /*theTimer*/)
|
||||||
struct tm* ct = &timeStruct;
|
struct tm* ct = &timeStruct;
|
||||||
#else
|
#else
|
||||||
time_t secs = (time_t)currentTime.tv_sec;
|
time_t secs = (time_t)currentTime.tv_sec;
|
||||||
struct tm* ct = gmtime(&secs);
|
struct tm timeStruct;
|
||||||
|
//struct tm* ct = gmtime(&secs);
|
||||||
|
#ifdef WIN32
|
||||||
|
gmtime_s(&timeStruct, &secs);
|
||||||
|
struct tm* ct = &timeStruct;
|
||||||
|
#else
|
||||||
|
struct tm* ct = gmtime_r(&secs, &timeStruct);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // if/else _WIN32_WCE
|
#endif // if/else _WIN32_WCE
|
||||||
|
ASSERT(NULL != ct);
|
||||||
PLOG(PL_INFO, "REPORT time>%02d:%02d:%02d.%06lu node>%lu ***************************************\n",
|
PLOG(PL_INFO, "REPORT time>%02d:%02d:%02d.%06lu node>%lu ***************************************\n",
|
||||||
ct->tm_hour, ct->tm_min, ct->tm_sec, currentTime.tv_usec, LocalNodeId());
|
ct->tm_hour, ct->tm_min, ct->tm_sec, currentTime.tv_usec, LocalNodeId());
|
||||||
if (IsSender())
|
if (IsSender())
|
||||||
{
|
{
|
||||||
PLOG(PL_INFO, "Local status:\n");
|
PLOG(PL_INFO, "Local status:\n");
|
||||||
|
|
@ -4925,6 +5094,14 @@ bool NormSession::OnReportTimeout(ProtoTimer& /*theTimer*/)
|
||||||
return true;
|
return true;
|
||||||
} // end NormSession::OnReportTimeout()
|
} // end NormSession::OnReportTimeout()
|
||||||
|
|
||||||
|
bool NormSession::OnUserTimeout(ProtoTimer& /*theTimer*/)
|
||||||
|
{
|
||||||
|
Notify(NormController::USER_TIMEOUT, (NormSenderNode*)NULL, (NormObject*)NULL);
|
||||||
|
return true;
|
||||||
|
} // end NormSession::OnUserTimeout(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NormSessionMgr::NormSessionMgr(ProtoTimerMgr& timerMgr,
|
NormSessionMgr::NormSessionMgr(ProtoTimerMgr& timerMgr,
|
||||||
ProtoSocket::Notifier& socketNotifier,
|
ProtoSocket::Notifier& socketNotifier,
|
||||||
ProtoChannel::Notifier* channelNotifier)
|
ProtoChannel::Notifier* channelNotifier)
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,8 @@ void NormTrace2(const struct timeval& currentTime,
|
||||||
clrFlag = ((NormCCFeedbackExtension&)ext).CCFlagIsSet(NormCC::CLR);
|
clrFlag = ((NormCCFeedbackExtension&)ext).CCFlagIsSet(NormCC::CLR);
|
||||||
// Print ccRtt (only valid if pcap file is from sender node)
|
// Print ccRtt (only valid if pcap file is from sender node)
|
||||||
double ccRtt = NormUnquantizeRtt(((NormCCFeedbackExtension&)ext).GetCCRtt());
|
double ccRtt = NormUnquantizeRtt(((NormCCFeedbackExtension&)ext).GetCCRtt());
|
||||||
PLOG(PL_ALWAYS, "ccRtt:%lf ", ccRtt);
|
double ccLoss = NormUnquantizeLoss32(((NormCCFeedbackExtension&)ext).GetCCLoss32());
|
||||||
|
PLOG(PL_ALWAYS, "ccRtt:%lf ccLoss:%lf ", ccRtt, ccLoss);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ JNIEXPORT jobject JNICALL PKGNAME(NormEvent_getObject)
|
||||||
NormObjectHandle objectHandle;
|
NormObjectHandle objectHandle;
|
||||||
jobject object = NULL;
|
jobject object = NULL;
|
||||||
|
|
||||||
objectHandle = (NormObjectHandle)env->GetLongField(obj,
|
objectHandle = (NormObjectHandle)env->GetLongField(obj, fid_NormEvent_objectHandle);
|
||||||
fid_NormEvent_objectHandle);
|
|
||||||
|
|
||||||
switch (NormObjectGetType(objectHandle)) {
|
switch (NormObjectGetType(objectHandle)) {
|
||||||
case NORM_OBJECT_DATA:
|
case NORM_OBJECT_DATA:
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,26 @@ JNIEXPORT void JNICALL PKGNAME(NormSession_setMulticastInterface)
|
||||||
env->ReleaseStringUTFChars(interfaceName, str);
|
env->ReleaseStringUTFChars(interfaceName, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL PKGNAME(NormSession_setSSM)
|
||||||
|
(JNIEnv *env, jobject obj, jstring sourceAddr) {
|
||||||
|
NormSessionHandle session;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
session = (NormSessionHandle)env->GetLongField(obj, fid_NormSession_handle);
|
||||||
|
|
||||||
|
str = env->GetStringUTFChars(sourceAddr, NULL);
|
||||||
|
|
||||||
|
if (!NormSetSSM(session, str)) {
|
||||||
|
env->ReleaseStringUTFChars(sourceAddr, str);
|
||||||
|
env->ThrowNew((jclass)env->NewLocalRef(jw_IOException), "Failed to set SSM source address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(sourceAddr, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL PKGNAME(NormSession_setTTL)
|
JNIEXPORT void JNICALL PKGNAME(NormSession_setTTL)
|
||||||
(JNIEnv *env, jobject obj, jbyte ttl) {
|
(JNIEnv *env, jobject obj, jbyte ttl) {
|
||||||
NormSessionHandle session;
|
NormSessionHandle session;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setRxPortReuse
|
||||||
/*
|
/*
|
||||||
* Class: mil_navy_nrl_norm_NormSession
|
* Class: mil_navy_nrl_norm_NormSession
|
||||||
* Method: setEcnSupport
|
* Method: setEcnSupport
|
||||||
* Signature: (ZZ)V
|
* Signature: (ZZZ)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setEcnSupport
|
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setEcnSupport
|
||||||
(JNIEnv *, jobject, jboolean, jboolean, jboolean);
|
(JNIEnv *, jobject, jboolean, jboolean, jboolean);
|
||||||
|
|
@ -55,6 +55,14 @@ JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setEcnSupport
|
||||||
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setMulticastInterface
|
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setMulticastInterface
|
||||||
(JNIEnv *, jobject, jstring);
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: mil_navy_nrl_norm_NormSession
|
||||||
|
* Method: setSSM
|
||||||
|
* Signature: (Ljava/lang/String;)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_setSSM
|
||||||
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: mil_navy_nrl_norm_NormSession
|
* Class: mil_navy_nrl_norm_NormSession
|
||||||
* Method: setTTL
|
* Method: setTTL
|
||||||
|
|
@ -321,7 +329,7 @@ JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_cancelWatermark
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: mil_navy_nrl_norm_NormSession
|
* Class: mil_navy_nrl_norm_NormSession
|
||||||
* Method: cancelWatermark
|
* Method: resetWatermark
|
||||||
* Signature: ()V
|
* Signature: ()V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_resetWatermark
|
JNIEXPORT void JNICALL Java_mil_navy_nrl_norm_NormSession_resetWatermark
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class NormEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the node.
|
* @return Returns the session.
|
||||||
*/
|
*/
|
||||||
public NormSession getSession() {
|
public NormSession getSession() {
|
||||||
if (sessionHandle == 0) {
|
if (sessionHandle == 0) {
|
||||||
|
|
@ -51,6 +51,9 @@ public class NormEvent {
|
||||||
return new NormNode(nodeHandle);
|
return new NormNode(nodeHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the object.
|
||||||
|
*/
|
||||||
public native NormObject getObject();
|
public native NormObject getObject();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import mil.navy.nrl.norm.enums.NormObjectType;
|
||||||
* @author Jason Rush
|
* @author Jason Rush
|
||||||
*/
|
*/
|
||||||
public class NormObject {
|
public class NormObject {
|
||||||
private long handle; // The pointer to the native NormInstanceHandle
|
private long handle; // The pointer to the native NormObjectHandle
|
||||||
|
|
||||||
NormObject(long handle) {
|
NormObject(long handle) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import mil.navy.nrl.norm.enums.NormSyncPolicy;
|
||||||
public class NormSession {
|
public class NormSession {
|
||||||
private static Map<Long, NormSession> normSessions = new HashMap<Long, NormSession>();
|
private static Map<Long, NormSession> normSessions = new HashMap<Long, NormSession>();
|
||||||
|
|
||||||
private long handle; // The pointer to the native NormInstanceHandle
|
private long handle; // The pointer to the native NormSessionHandle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package protected constructor is invoked by NormInstance
|
* Package protected constructor is invoked by NormInstance
|
||||||
|
|
@ -38,7 +38,6 @@ public class NormSession {
|
||||||
|
|
||||||
public void destroySession() {
|
public void destroySession() {
|
||||||
normSessions.remove(handle);
|
normSessions.remove(handle);
|
||||||
|
|
||||||
destroySessionNative();
|
destroySessionNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,6 +63,9 @@ public class NormSession {
|
||||||
public native void setMulticastInterface(String interfaceName)
|
public native void setMulticastInterface(String interfaceName)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
|
public native void setSSM(String sourceAddr)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
public native void setTTL(byte ttl) throws IOException;
|
public native void setTTL(byte ttl) throws IOException;
|
||||||
|
|
||||||
public native void setTOS(byte tos) throws IOException;
|
public native void setTOS(byte tos) throws IOException;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ public enum NormEventType {
|
||||||
NORM_TX_RATE_CHANGED,
|
NORM_TX_RATE_CHANGED,
|
||||||
NORM_LOCAL_SENDER_CLOSED,
|
NORM_LOCAL_SENDER_CLOSED,
|
||||||
NORM_REMOTE_SENDER_NEW,
|
NORM_REMOTE_SENDER_NEW,
|
||||||
|
NORM_REMOTE_SENDER_RESET,
|
||||||
|
NORM_REMOTE_SENDER_ADDRESS,
|
||||||
NORM_REMOTE_SENDER_ACTIVE,
|
NORM_REMOTE_SENDER_ACTIVE,
|
||||||
NORM_REMOTE_SENDER_INACTIVE,
|
NORM_REMOTE_SENDER_INACTIVE,
|
||||||
NORM_REMOTE_SENDER_PURGED,
|
NORM_REMOTE_SENDER_PURGED,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 by General Dynamics Advanced Information Systems
|
|
||||||
* Classification: UNCLASSIFIED
|
|
||||||
*/
|
|
||||||
package mil.navy.nrl.norm.enums;
|
package mil.navy.nrl.norm.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -11,6 +8,7 @@ package mil.navy.nrl.norm.enums;
|
||||||
*
|
*
|
||||||
* @author Jason Rush
|
* @author Jason Rush
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public enum NormSyncPolicy {
|
public enum NormSyncPolicy {
|
||||||
NORM_SYNC_CURRENT,
|
NORM_SYNC_CURRENT,
|
||||||
NORM_SYNC_STREAM,
|
NORM_SYNC_STREAM,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 by General Dynamics Advanced Information Systems
|
|
||||||
* Classification: UNCLASSIFIED
|
|
||||||
*/
|
|
||||||
package mil.navy.nrl.norm.io;
|
package mil.navy.nrl.norm.io;
|
||||||
|
|
||||||
import mil.navy.nrl.norm.NormEvent;
|
import mil.navy.nrl.norm.NormEvent;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 by General Dynamics Advanced Information Systems
|
|
||||||
* Classification: UNCLASSIFIED
|
|
||||||
*/
|
|
||||||
package mil.navy.nrl.norm.io;
|
package mil.navy.nrl.norm.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -33,6 +29,7 @@ public class NormInputStream extends InputStream {
|
||||||
private Object closeLock;
|
private Object closeLock;
|
||||||
|
|
||||||
private boolean bufferIsEmpty;
|
private boolean bufferIsEmpty;
|
||||||
|
private boolean receivedEof;
|
||||||
|
|
||||||
public NormInputStream(String address, int port) throws IOException {
|
public NormInputStream(String address, int port) throws IOException {
|
||||||
// Create the NORM instance
|
// Create the NORM instance
|
||||||
|
|
@ -50,6 +47,7 @@ public class NormInputStream extends InputStream {
|
||||||
closeLock = new Object();
|
closeLock = new Object();
|
||||||
|
|
||||||
bufferIsEmpty = true;
|
bufferIsEmpty = true;
|
||||||
|
receivedEof = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void openDebugLog(String filename) throws IOException {
|
public synchronized void openDebugLog(String filename) throws IOException {
|
||||||
|
|
@ -198,12 +196,12 @@ public class NormInputStream extends InputStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
while (normInstance.hasNextEvent(0, 0)) {
|
while (bufferIsEmpty || normInstance.hasNextEvent(0, 0)) {
|
||||||
processEvent();
|
processEvent();
|
||||||
}
|
|
||||||
|
|
||||||
while (bufferIsEmpty) {
|
if (receivedEof) {
|
||||||
processEvent();
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normStream == null) {
|
if (normStream == null) {
|
||||||
|
|
@ -254,6 +252,9 @@ public class NormInputStream extends InputStream {
|
||||||
case NORM_RX_OBJECT_ABORTED:
|
case NORM_RX_OBJECT_ABORTED:
|
||||||
case NORM_RX_OBJECT_COMPLETED:
|
case NORM_RX_OBJECT_COMPLETED:
|
||||||
normStream = null;
|
normStream = null;
|
||||||
|
|
||||||
|
// Signal that the stream has ended
|
||||||
|
receivedEof = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 by General Dynamics Advanced Information Systems
|
|
||||||
* Classification: UNCLASSIFIED
|
|
||||||
*/
|
|
||||||
package mil.navy.nrl.norm.io;
|
package mil.navy.nrl.norm.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 by General Dynamics Advanced Information Systems
|
|
||||||
* Classification: UNCLASSIFIED
|
|
||||||
*/
|
|
||||||
package mil.navy.nrl.norm.io;
|
package mil.navy.nrl.norm.io;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
||||||
|
|
@ -58,18 +58,20 @@ NORM_TX_OBJECT_PURGED = 7
|
||||||
NORM_TX_RATE_CHANGED = 8
|
NORM_TX_RATE_CHANGED = 8
|
||||||
NORM_LOCAL_SENDER_CLOSED = 9
|
NORM_LOCAL_SENDER_CLOSED = 9
|
||||||
NORM_REMOTE_SENDER_NEW = 10
|
NORM_REMOTE_SENDER_NEW = 10
|
||||||
NORM_REMOTE_SENDER_ACTIVE = 11
|
NORM_REMOTE_SENDER_RESET = 11
|
||||||
NORM_REMOTE_SENDER_INACTIVE = 12
|
NORM_REMOTE_SENDER_ADDRESS = 12
|
||||||
NORM_REMOTE_SENDER_PURGED = 13
|
NORM_REMOTE_SENDER_ACTIVE = 13
|
||||||
NORM_RX_CMD_NEW = 14
|
NORM_REMOTE_SENDER_INACTIVE = 14
|
||||||
NORM_RX_OBJECT_NEW = 15
|
NORM_REMOTE_SENDER_PURGED = 15
|
||||||
NORM_RX_OBJECT_INFO = 16
|
NORM_RX_CMD_NEW = 16
|
||||||
NORM_RX_OBJECT_UPDATED = 17
|
NORM_RX_OBJECT_NEW = 17
|
||||||
NORM_RX_OBJECT_COMPLETED = 18
|
NORM_RX_OBJECT_INFO = 18
|
||||||
NORM_RX_OBJECT_ABORTED = 19
|
NORM_RX_OBJECT_UPDATED = 19
|
||||||
NORM_GRTT_UPDATED = 20
|
NORM_RX_OBJECT_COMPLETED = 20
|
||||||
NORM_CC_ACTIVE = 21
|
NORM_RX_OBJECT_ABORTED = 21
|
||||||
NORM_CC_INACTIVE = 22
|
NORM_GRTT_UPDATED = 22
|
||||||
|
NORM_CC_ACTIVE = 23
|
||||||
|
NORM_CC_INACTIVE = 24
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,10 +154,13 @@ def get_libnorm():
|
||||||
ctypes.c_bool, ctypes.c_bool]
|
ctypes.c_bool, ctypes.c_bool]
|
||||||
|
|
||||||
libnorm.NormSetMulticastInterface.restype = ctypes.c_bool
|
libnorm.NormSetMulticastInterface.restype = ctypes.c_bool
|
||||||
libnorm.NormSetMulticastInterface.argtypes = [ctypes.c_void_p,
|
libnorm.NormSetMulticastInterface.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||||
ctypes.c_char_p]
|
|
||||||
libnorm.NormSetMulticastInterface.errcheck = errcheck_bool
|
libnorm.NormSetMulticastInterface.errcheck = errcheck_bool
|
||||||
|
|
||||||
|
libnorm.NormSetSSM.restype = ctypes.c_bool
|
||||||
|
libnorm.NormSetSSM.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||||
|
libnorm.NormSetSSM.errcheck = errcheck_bool
|
||||||
|
|
||||||
libnorm.NormSetTTL.restype = ctypes.c_bool
|
libnorm.NormSetTTL.restype = ctypes.c_bool
|
||||||
libnorm.NormSetTTL.argtypes = [ctypes.c_void_p, ctypes.c_uint8]
|
libnorm.NormSetTTL.argtypes = [ctypes.c_void_p, ctypes.c_uint8]
|
||||||
libnorm.NormSetTTL.errcheck = errcheck_bool
|
libnorm.NormSetTTL.errcheck = errcheck_bool
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,10 @@ class Event(object):
|
||||||
return "NORM_LOCAL_SENDER_CLOSED"
|
return "NORM_LOCAL_SENDER_CLOSED"
|
||||||
elif self.type == c.NORM_REMOTE_SENDER_NEW:
|
elif self.type == c.NORM_REMOTE_SENDER_NEW:
|
||||||
return "NORM_REMOTE_SENDER_NEW"
|
return "NORM_REMOTE_SENDER_NEW"
|
||||||
|
elif self.type == c.NORM_REMOTE_SENDER_RESET:
|
||||||
|
return "NORM_REMOTE_SENDER_RESET"
|
||||||
|
elif self.type == c.NORM_REMOTE_SENDER_ADDRESS:
|
||||||
|
return "NORM_REMOTE_SENDER_ADDRESS"
|
||||||
elif self.type == c.NORM_REMOTE_SENDER_ACTIVE:
|
elif self.type == c.NORM_REMOTE_SENDER_ACTIVE:
|
||||||
return "NORM_REMOTE_SENDER_ACTIVE"
|
return "NORM_REMOTE_SENDER_ACTIVE"
|
||||||
elif self.type == c.NORM_REMOTE_SENDER_INACTIVE:
|
elif self.type == c.NORM_REMOTE_SENDER_INACTIVE:
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,9 @@ class Session(object):
|
||||||
def setMulticastInterface(self, iface):
|
def setMulticastInterface(self, iface):
|
||||||
libnorm.NormSetMulticastInterface(self, iface)
|
libnorm.NormSetMulticastInterface(self, iface)
|
||||||
|
|
||||||
|
def setSSM(self, srcAddr):
|
||||||
|
libnorm.NormSetSSM(self, srcAddr)
|
||||||
|
|
||||||
def setTTL(self, ttl):
|
def setTTL(self, ttl):
|
||||||
libnorm.NormSetTTL(self, ttl)
|
libnorm.NormSetTTL(self, ttl)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
/* Process model C++ form file: norm_protolib.pr.cpp */
|
/* Process model C++ form file: norm_protolib.pr.cpp */
|
||||||
/* Portions of this file copyright 1992-2006 by OPNET Technologies, Inc. */
|
/* Portions of this file copyright 1992-2006 by OPNET Technologies, Inc. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This variable carries the header into the object file */
|
/* This variable carries the header into the object file */
|
||||||
const char norm_protolib_pr_cpp [] = "MIL_3_Tfile_Hdr_ 120A 30A modeler 7 464DEF85 464DEF85 1 wn12jh Jim@Hauser 0 0 none none 0 0 none 0 0 0 0 0 0 0 0 10de 3 ";
|
const char norm_protolib_pr_cpp [] = "MIL_3_Tfile_Hdr_ 120A 30A modeler 7 464DEF85 464DEF85 1 wn12jh Jim@Hauser 0 0 none none 0 0 none 0 0 0 0 0 0 0 0 10de 3 ";
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue