pull/2/head
Jeff Weston 2019-09-11 11:47:56 -04:00
parent 4bd6a9acb0
commit cca3e58c8b
32 changed files with 2784 additions and 1879 deletions

View File

@ -6,7 +6,7 @@
<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.2 (Linux)">
<META NAME="AUTHOR" CONTENT="Robert Adamson">
<META NAME="CREATED" CONTENT="20040824;15180000">
<META NAME="CHANGED" CONTENT="20050304;10303500">
<META NAME="CHANGED" CONTENT="20050420;17075300">
<META NAME="DESCRIPTION" CONTENT="NORM Object Functions 42 NORM Object Functions NORM_OBJECT_STREAM NORM Sender Functions 19 NORM Sender Functions ">
<META NAME="KEYWORDS" CONTENT="norm object value application function ">
<STYLE>
@ -64,7 +64,9 @@ United States Naval Research Laboratory (NRL). The NORM protocol
provides general purpose reliable data transport for applications
wishing to use Internet Protocol (IP) Multicast services for group
data delivery. NORM can also support unicast (point-to-point) data
communication and may be used for such when deemed appropriate.</P>
communication and may be used for such when deemed appropriate. The
current NORM protocol specification is given in the Internet
Engineering Task Force RFC 3940.</P>
<P CLASS="western" STYLE="font-style: normal">The NORM protocol is
designed to provide end-to-end reliable transport of bulk data
objects or streams over generic IP multicast routing and forwarding
@ -82,9 +84,10 @@ to allow different types of applications or possibly other higher
level transport protocols to utilize its service in different ways.
The protocol leverages the use of FEC-based repair and other proven
reliable multicast transport techniques in its design.</P>
<H1 CLASS="western" ALIGN=CENTER STYLE="page-break-before: always">Table
of Contents</H1>
<H1 CLASS="western" ALIGN=CENTER STYLE="page-break-before: always">Contents</H1>
<DIV ID="Table of Contents1" DIR="LTR">
<P STYLE="margin-top: 0.25in; font-style: normal"><BR>
</P>
<P STYLE="margin-top: 0.25in; font-style: normal"><FONT FACE="Helvetica, sans-serif"><B>Overview</B></FONT></P>
<P STYLE="margin-top: 0.17in; font-style: normal"><FONT SIZE=2><B>API
Initialization</B></FONT></P>
@ -112,7 +115,7 @@ of Contents</H1>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormEventType">NormEventType</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormEvent">NormEvent</A></FONT></P>
<P STYLE="margin-top: 0.17in; font-style: normal"><FONT SIZE=2><B>API
Initialization</B></FONT></P>
Initialization and Operation</B></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormCreateInstance()">NormCreateInstance()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormDestroyInstance()">NormDestroyInstance()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetCacheDirectory()">NormSetCacheDirectory()</A></FONT></P>
@ -122,7 +125,10 @@ of Contents</H1>
Creation and Control</B></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormCreateSession()">NormCreateSession()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormDestroySession()">NormDestroySession()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetUserData()">NormSetUserData()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormGetUserData()">NormGetUserData()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormGetLocalNodeId()">NormGetLocalNodeId()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTxPort()">NormSetTxPort()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetMulticastInterface()">NormSetMulticastInterface()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTTL()">NormSetTTL()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTOS()">NormSetTOS()</A></FONT></P>
@ -132,6 +138,7 @@ of Contents</H1>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormStartSender()">NormStartSender()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormStopSender()">NormStopSender()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTransmitRate()">NormSetTransmitRate()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTxSocketBuffer()">NormSetTxSocketBuffer()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetCongestionControl()">NormSetCongestionControl()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetTransmitRateBounds()">NormSetTransmitRateBounds()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetAutoParity()">NormSetAutoParity()</A></FONT></P>
@ -152,6 +159,7 @@ of Contents</H1>
Receiver Functions</B></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormStopReceiver()">NormStopReceiver()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetRxSocketBuffer()">NormSetRxSocketBuffer()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetSilentReceiver()">NormSetSilentReceiver()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormSetDefaultUnicastNack()">NormSetDefaultUnicastNack()</A></FONT></P>
<P STYLE="margin-left: 0.17in; margin-top: 0in; font-style: normal"><FONT SIZE=2><A HREF="#NormNodeSetUnicastNack()">NormNodeSetUnicastNack()</A></FONT></P>
@ -476,7 +484,7 @@ which the event applies. NORM protocol events are made available to
the application via the <FONT FACE="Courier"><A HREF="#NormGetNextEvent()">NormGetNextEvent()</A></FONT>
function call.
</P>
<H2 CLASS="western">API Initialization</H2>
<H2 CLASS="western">API Initialization and Operation</H2>
<P CLASS="western" STYLE="font-style: normal">The first step in using
the NORM API is to create an &quot;instance&quot; of the NORM
protocol engine. Note that multiple instances may be created by the
@ -488,7 +496,7 @@ single NORM API instance.</P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2><A HREF="#NormInstanceHandle">NormInstanceHandle</A>
<A HREF="#NormCreateInstance()">NormCreateInstance()</A>;</FONT></FONT></P>
NormCreateInstance(bool priorityBoost = false);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function creates
an instance of a NORM protocol engine and is the necessary first step
@ -496,8 +504,18 @@ before any other API functions may be used. With the instantiation
of the NORM protocol engine, an operating system thread is created
for protocol execution. The returned <FONT FACE="Courier"><A HREF="#NormInstanceHandle">NormInstanceHandle</A>
</FONT>value may be used in subsequent API calls as needed, such
<FONT FACE="Courier">NormCreateSesssion()</FONT>, etc.
</P>
<FONT FACE="Courier">NormCreateSesssion()</FONT>, etc. The optional
<FONT FACE="Courier"><U>priorityBoost</U></FONT> parameter, when set
to a value of <FONT FACE="Courier"><I>true</I></FONT>, specifies that
the NORM protocol engine thread be run with higher priority
scheduling. On Win32 platforms, this corresponds to
<FONT FACE="Courier"><I>THREAD_PRIORITY_TIME_CRITICAL</I></FONT> and
on Unix systems with the <FONT FACE="Courier">sched_setscheduler()</FONT>
API, an attempt to get the maximum allowed <FONT FACE="Courier"><I>SCHED_FIFO</I></FONT>
priority is made. The use of this option should be carefully
evaluated since, depending upon the application's scheduling priority
and NORM API usage, this may have adverse effects instead of a
guaranteed performance increase!</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">A value of
<FONT FACE="Courier">NORM_INSTANCE_INVALID</FONT> is returned upon
@ -587,34 +605,34 @@ enumerates the possible <FONT FACE="Courier"><A HREF="#NormEvent">NormEvent</A>
and describes how these notifications should be interpreted as they
are retrieved by the application via the <FONT FACE="Courier"><A HREF="#NormGetNextEvent()">NormGetNextEvent()</A></FONT>
function call.</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=123*>
<COL WIDTH=133*>
<TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=269>
<COL WIDTH=293>
<TR>
<TD COLSPAN=2 WIDTH=100% VALIGN=TOP>
<TD COLSPAN=2 WIDTH=576 VALIGN=TOP>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Sender Notification Event Types:</B></P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_QUEUE_VACANCY</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that there is room for additional transmit
objects to be enqueued, or, if the handle of <FONT FACE="Courier"><I>NORM_OBJECT_STREAM</I></FONT>
is given in the event &quot;object&quot; field, the application
may successfully write to the indicated stream.</P>
may successfully write to the indicated stream object.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_QUEUE_EMPTY</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates the NORM protocol engine has no new data
pending transmission and the application may enqueue additional
@ -622,11 +640,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_OBJECT_SENT</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the transport object referenced by the
event's &quot;object&quot; field has completed at least one pass
@ -638,11 +656,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_OBJECT_PURGED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the NORM protocol engine will no longer
refer to the transport object identified by the event's &quot;object'
@ -657,11 +675,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_LOCAL_SERVER_CLOSED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when the NORM protocol engine completes the
&quot;graceful shutdown&quot; of its participation as a sender in
@ -669,17 +687,17 @@ function call.</P>
</TD>
</TR>
<TR>
<TD COLSPAN=2 WIDTH=100% VALIGN=TOP>
<TD COLSPAN=2 WIDTH=576 VALIGN=TOP>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Receiver Notification Event Types:</B></P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_NEW</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when a receiver first receives
messages from a specific remote NORM server. This marks the
@ -688,11 +706,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_ACTIVE</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when a previously inactive (or new) remote
server is detected operating as an active sender within the
@ -700,11 +718,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_INACTIVE</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted after a significant period of inactivity (no
sender messages received) of a specific NORM sender within the
@ -713,22 +731,22 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_PURGED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when the NORM protocol engine frees resources
for, and thus invalidates the indicated &quot;node&quot; handle.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_NEW</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when reception of a new transport object
begins and marks the beginning of the interval during which the
@ -737,33 +755,33 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_INFO</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when the NORM_INFO content for the
indicated &quot;object&quot; is received.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_UPDATED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the identified receive &quot;object&quot;
has newly received data content.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_COMPLETED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when a receive object is completely received,
including available NORM_INFO content. Unless the application
@ -773,11 +791,11 @@ function call.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_ABORTED</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when a pending receive object's
transmission is aborted by the remote sender. Unless the
@ -787,17 +805,17 @@ function call.</P>
</TD>
</TR>
<TR>
<TD COLSPAN=2 WIDTH=100% VALIGN=TOP>
<TD COLSPAN=2 WIDTH=576 VALIGN=TOP>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Miscellaneous Notification Event Types</B></P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=48%>
<TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_EVENT_INVALID</I></FONT></P>
</TD>
<TD WIDTH=52%>
<TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This <A HREF="#NormEventType">NormEventType</A> indicates an invalid or &quot;null&quot;
notification which should be ignored.</P>
@ -818,7 +836,7 @@ even when no event is pending. In these cases, the return value is
<P CLASS="western">WIN32 Note: A future version of this API will
provide an option to have a user-defined Window message posted when a
NORM API event is pending. (Also some event filtering calls may be
provided (e.g. avoid the potentially numerous <FONT FACE="Courier"><I>RX_OBJECT_UPDATED</I></FONT>
provided (e.g. avoid the potentially numerous <FONT FACE="Courier"><I>NORM_RX_OBJECT_UPDATED</I></FONT>
events if undesired)).</P>
<H3 CLASS="functionheading-western"><A NAME="NormGetDescriptor()">NormGetDescriptor()</A></H3>
<H4 CLASS="western">Synopsis</H4>
@ -845,8 +863,8 @@ usage, the NORM descriptor should be treated as a &quot;read&quot;
descriptor.</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">A descriptor is
returned which is valid until a call to <A HREF="#NormDestroyInstance()">NormDestroyInstance()</A> is
made. Upon error, a value of <I><FONT FACE="Courier">NORM_DESCRIPTOR_INVALID</FONT></I>
returned which is valid until a call to <FONT FACE="Courier"><A HREF="#NormDestroyInstance()">NormDestroyInstance()</A></FONT>
is made. Upon error, a value of <I><FONT FACE="Courier">NORM_DESCRIPTOR_INVALID</FONT></I>
is returned.</P>
<H2 CLASS="western">Session Creation and Control</H2>
<H3 CLASS="functionheading-western"><A NAME="NormCreateSession()">NormCreateSession()</A></H3>
@ -866,26 +884,26 @@ is made to <FONT FACE="Courier"><A HREF="#NormStartSender()">NormStartSender()</
<FONT FACE="Courier"><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT> to join the specified
multicast group (if applicable) and start protocol operation. The
following parameters are required in this function call:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=50*>
<COL WIDTH=206*>
<TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=101>
<COL WIDTH=461>
<TR VALIGN=TOP>
<TD WIDTH=20%>
<TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">instance</FONT></P>
</TD>
<TD WIDTH=80%>
<TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This must be a valid <FONT FACE="Courier"><A HREF="#NormInstanceHandle">NormInstanceHandle</A></FONT>
previously obtained with a call to <FONT FACE="Courier"><A HREF="#NormCreateInstance()">NormCreateInstance()</A></FONT>.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=20%>
<TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">address</FONT></P>
</TD>
<TD WIDTH=80%>
<TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This points to a string containing an IP address (e.g. dotted
decimal IPv4 address (or IPv6 address) or name resolvable to a
@ -903,11 +921,11 @@ following parameters are required in this function call:</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=20%>
<TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">port</FONT></P>
</TD>
<TD WIDTH=80%>
<TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This must be a valid, unused port number corresponding to the
desired NORM session address. See the <U><FONT FACE="Courier">address</FONT></U>
@ -915,11 +933,11 @@ following parameters are required in this function call:</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=20%>
<TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">localId</FONT></P>
</TD>
<TD WIDTH=80%>
<TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
The <FONT FACE="Courier">localId</FONT> parameter specifies the
<FONT FACE="Courier"><A HREF="#NormNodeId">NormNodeId</A></FONT> that should be used to
@ -965,6 +983,40 @@ explicitly retained <FONT FACE="Courier">NormObjectHandles</FONT>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no
returned values.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetUserData()">NormSetUserData()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>void
NormSetUserData(<A HREF="#NormSessionHandle">NormSessionHandle</A> session, const void* userData);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function allows
the application to attach a value to the previously-created
<I>NormSession</I> instance specified by the <FONT FACE="Courier"><U>session</U></FONT>
parameter. This value is not used or interpreted by NORM, but is
available to the application for use at the programmer's discretion.
The set <FONT FACE="Courier"><U>userData</U></FONT> value can be
later retrieved using the <FONT FACE="Courier"><A HREF="#NormGetUserData()">NormGetUserData()</A></FONT>
function call.</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no
returned values.</P>
<H3 CLASS="functionheading-western"><A NAME="NormGetUserData()">NormGetUserData()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>const
void* NormGetUserData(<A HREF="#NormSessionHandle">NormSessionHandle</A> session);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function retrieves
the &quot;user data&quot; value set for the specified session with a
prior call to <FONT FACE="Courier"><A HREF="#NormSetUserData()">NormSetUserData()</A></FONT>.</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function returns
the user data value set for the specified session. If no user data
value has been previously set a <FONT FACE="Courier"><I>NULL</I></FONT>
(i.e., <FONT FACE="Courier"><I>(const void*)0</I></FONT>) value is
returned.</P>
<H3 CLASS="functionheading-western"><A NAME="NormGetLocalNodeId()">NormGetLocalNodeId()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
@ -984,6 +1036,34 @@ network address.</P>
indicates the <I>NormNode</I> identifier used by the NORM protocol
engine for the local application's participation in the specified
<I>NormSession</I>.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetTxPort()">NormSetTxPort()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>void
NormSetTxPort(<A HREF="#NormSessionHandle">NormSessionHandle</A> session,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned
short txPort);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function is used
to force NORM to use a specific port number for UDP packets sent for
the specified <FONT FACE="Courier"><U>session</U></FONT>. By
default, NORM uses separate port numbers for packet transmission and
session packet reception (the receive port is specified as part of
the <FONT FACE="Courier"><A HREF="#NormCreateSession()">NormCreateSession()</A></FONT> call), allowing
the operating system to pick a freely available port for
transmission. This call allows the application to pick a specific
port number for transmission, and furthermore allows the application
to even specify the same port number for transmission as is used for
reception. However, the use of separate transmit/receive ports
allows NORM to discriminate when unicast feedback is occurring and
thus it is not generally recommended that the transmit port be set to
the same value as the <FONT FACE="Courier"><U>session</U></FONT>
receive port. This call <I>must</I> be made <I>before</I> any calls
to <FONT FACE="Courier"><A HREF="#NormStartSender()">NormStartSender()</A></FONT> or
<FONT FACE="Courier"><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT> to succeed.</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no
return values.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetMulticastInterface()">NormSetMulticastInterface()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
@ -1118,26 +1198,26 @@ such as congestion control and/or group round-trip timing (GRTT)
feedback collection and application API activity such as posting of
sender-related <I>NormEvents</I>. The parameters required for this
function call include:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=56*>
<COL WIDTH=200*>
<TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=106>
<COL WIDTH=456>
<TR VALIGN=TOP>
<TD WIDTH=22%>
<TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>session</U></FONT></P>
</TD>
<TD WIDTH=78%>
<TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This must be a valid <FONT FACE="Courier"><A HREF="#NormSessionHandle">NormSessionHandle</A></FONT>
previously obtained with a call to <FONT FACE="Courier"><A HREF="#NormCreateSession()">NormCreateSession()</A></FONT>.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=22%>
<TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>bufferSpace</U></FONT></P>
</TD>
<TD WIDTH=78%>
<TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This specifies the maximum memory space the NORM protocol engine
is allowed to use to buffer any sender calculated FEC segments and
@ -1155,11 +1235,11 @@ function call include:</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=22%>
<TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>segmentSize</U></FONT></P>
</TD>
<TD WIDTH=78%>
<TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the maximum <I>payload</I> size (in bytes) of
NORM sender messages (<I>not</I> including any NORM message header
@ -1181,21 +1261,21 @@ function call include:</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=22%>
<TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>blockSize</U></FONT></P>
</TD>
<TD WIDTH=78%>
<TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the number of source symbol segments (packets)
per coding block, for the systematic Reed-Solomon FEC code used in
the current NORM implementation. For traditional systematic block
code &quot;<I>(n,k)</I>&quot; nomenclature, the <FONT FACE="Courier"><U>blockSize</U></FONT>
value corresponds to <I>(n-k).</I> NORM logically segments
transport object data content into coding blocks and the <FONT FACE="Courier"><U>blockSize</U></FONT>
parameter determines the number of source symbol segments
(packets) comprising a single coding block where each source
symbol segment is up to <FONT FACE="Courier"><U>segmentSize</U></FONT>
value corresponds to <I>&quot;k&quot;.</I> NORM logically
segments transport object data content into coding blocks and the
<FONT FACE="Courier"><U>blockSize</U></FONT> parameter determines
the number of source symbol segments (packets) comprising a single
coding block where each source symbol segment is up to <FONT FACE="Courier"><U>segmentSize</U></FONT>
bytes in length.. A given block's parity symbol segments are
calculated using the corresponding set of source symbol segments.
The maximum <FONT FACE="Courier"><U>blockSize</U></FONT> allowed
@ -1205,11 +1285,11 @@ function call include:</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=22%>
<TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>numParity</U></FONT></P>
</TD>
<TD WIDTH=78%>
<TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the maximum number of parity symbol segments
(packets) the sender is willing to <I>calculate</I> per FEC coding
@ -1217,7 +1297,7 @@ function call include:</P>
the corresponding <FONT FACE="Courier"><U>blockSize</U></FONT>
source symbol segments. In the &quot;<I>(n,k)&quot;</I>
nomenclature mention above, the <FONT FACE="Courier"><U>numParity</U></FONT>
value corresponds to &quot;<I>k</I>&quot;. A property of the
value corresponds to &quot;<I>n-k</I>&quot;. A property of the
Reed-Solomon FEC codes used in the current NORM implementation is
that one parity segment can fill any one erasure (missing segment
(packet)) for a coding block. For a given <FONT FACE="Courier"><U>blockSize</U></FONT>,
@ -1312,6 +1392,36 @@ readjust the rate unless disabled.
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no
return values.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetTxSocketBuffer()">NormSetTxSocketBuffer()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>bool
NormSetTxSocketBuffer(<A HREF="#NormSessionHandle">NormSessionHandle</A>&nbsp;session,
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned
int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bufferSize);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function can be
used to set a non-default socket buffer size for the UDP socket used
by the specified NORM <FONT FACE="Courier"><U>session</U></FONT> for
data transmission. The <FONT FACE="Courier"><U>bufferSize</U></FONT>
parameter specifies the desired socket buffer size in bytes. Large
transmit socket buffer sizes may be necessary to achieve high
throughput rates when NORM, as a user-space process, is unable to
precisely time its packet transmissions. Similarly, NORM receivers
may need to set large receive socket buffer sizes to achieve
sustained high data rate reception (see <FONT FACE="Courier"><A HREF="#NormSetRxSocketBuffer()">NormSetRxSocketBuffer()</A></FONT>).
</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function returns
<FONT FACE="Courier"><I>true</I></FONT> upon success and <FONT FACE="Courier"><I>false</I></FONT>
upon failure. Possible failure modes include an invalid session
parameter, a call to <FONT FACE="Courier"><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT>
or <FONT FACE="Courier"><A HREF="#NormStartSender()">NormStartSender()</A></FONT> has not yet been
made for the session, or an invalid <FONT FACE="Courier"><U>bufferSize</U></FONT>
was given. Note some operating systems may require additional
configuration to use non-standard socket buffer sizes.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetCongestionControl()">NormSetCongestionControl()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
@ -1424,7 +1534,7 @@ NormSetGrttEstimate(<A HREF="#NormSessionHandle">NormSessionHandle</A>&nbsp;sess
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function sets the
sender's estimate of group round-trip timing (GRTT). This function
is expected to most typically used to initialize ther sender's GRTT
is expected to most typically used to initialize the sender's GRTT
estimate prior to the call to <FONT FACE="Courier"><A HREF="#NormStartSender()">NormStartSender()</A></FONT>
when the application has <I>a priori</I> confidence that the default
initial GRTT value of 0.5 second is inappropriate. The sender GRTT
@ -1433,9 +1543,9 @@ after sender startup or if this call is made while sender operation
is active. For experimental purposes (or very special application
needs), this API provides a mechanism to control or disable the
sender GRTT update process (see <FONT FACE="Courier">NormSetGrttProbing()</FONT>).
The grtt value will be limited to the maximum GRTT as set (see
<FONT FACE="Courier">NormSetGrttMax()) </FONT>or the default maximum
of 10 seconds.
The <FONT FACE="Courier"><U>grtt</U></FONT> value will be limited to
the maximum GRTT as set (see <FONT FACE="Courier">NormSetGrttMax())
</FONT>or the default maximum of 10 seconds.
</P>
<P CLASS="western" STYLE="font-style: normal">The sender GRTT is
advertised to the receiver group and is used to scale various NORM
@ -2064,6 +2174,39 @@ related resources are then freed.</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no
return values.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetRxSocketBuffer()">NormSetRxSocketBuffer()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>bool
NormSetRxSocketBuffer(<A HREF="#NormSessionHandle">NormSessionHandle</A> session,
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned
int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bufferSize);</FONT></FONT></P>
<H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function allows
the application to set an alternative, non-default buffer size for
the UDP socket used by the specified NORM <FONT FACE="Courier"><U>session</U></FONT>
for packet reception. This may be necessary for high speed NORM
sessions where the UDP receive socket buffer becomes a bottleneck
when the NORM protocol engine (which is running as a user-space
process) doesn't get to service the receive socket quickly enough
resulting in packet loss when the socket buffer overflows. The
<FONT FACE="Courier"><U>bufferSize</U></FONT> parameter specifies the
socket buffer size in bytes. Different operating systems and
sometimes system configurations allow different ranges of socket
buffer sizes to be set. Note that a call to <FONT FACE="Courier"><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT>
(or <FONT FACE="Courier"><A HREF="#NormStartSender()">NormStartSender()</A></FONT>) must have been
previously made for this call to succeed (i.e., the socket must be
already open).</P>
<H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function returns
<FONT FACE="Courier"><I>true</I></FONT> upon success and <FONT FACE="Courier"><I>false</I></FONT>
upon failure. Possible reasons for failure include, 1) the specified
<FONT FACE="Courier"><U>session</U></FONT> is not valid, 2) that NORM
&quot;receiver&quot; (or &quot;sender&quot;) operation has not yet
been started for the given <FONT FACE="Courier"><U>session</U></FONT>,
or 3) an invalid <FONT FACE="Courier"><U>bufferSize</U></FONT>
specification was given.</P>
<H3 CLASS="functionheading-western"><A NAME="NormSetSilentReceiver()">NormSetSilentReceiver()</A></H3>
<H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
@ -2154,32 +2297,32 @@ participation in the repair process. By limiting receivers to only
request repair of objects in which they are really interested in
receiving, some overall savings in unnecessary network loading might
be realized. Available nacking modes include:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0 STYLE="page-break-inside: avoid">
<COL WIDTH=131*>
<COL WIDTH=125*>
<TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=231>
<COL WIDTH=332>
<TR VALIGN=TOP>
<TD WIDTH=51%>
<TD WIDTH=231>
<P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_NONE</I></FONT></P>
</TD>
<TD WIDTH=49%>
<TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Do not transmit any repair requests for the newly received object.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=51%>
<TD WIDTH=231>
<P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_INFO_ONLY</I></FONT></P>
</TD>
<TD WIDTH=49%>
<TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Transmit repair requests for NORM_INFO content only as needed.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=51%>
<TD WIDTH=231>
<P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_NORMAL</I></FONT></P>
</TD>
<TD WIDTH=49%>
<TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Transmit repair requests for entire object as needed.</P>
</TD>

Binary file not shown.

View File

@ -1,5 +1,18 @@
NORM Version History
Version 1.3b1
=============
- Prevented pile-up of TX_QUEUE_VACANCY notifications
- Fix/optimization to ProtoDispatcher threaded operation
to prevent possible (although minor) race condition
during threaded operation.
- Added NORM API calls: NormSetTxSocketBuffer(),
NormSetRxSocketBuffer(), NormSetUserData(),
NormGetUserData(), and implemented overlooked
NormGetDescriptor()
- Thanks again to Charlie Davis for finding some
performance deficiencies.
Version 1.2b9
=============
- Fixed bugs with NormServerNode::retrieval_pool mgmnt

View File

@ -2,6 +2,12 @@
#include "normApi.h"
#include "normSession.h"
#ifdef WIN32
#ifndef _WIN32_WCE
#include <io.h> // for _mktemp()
#endif // !_WIN32_WCE
#endif // WIN32
// const defs
const NormInstanceHandle NORM_INSTANCE_INVALID = ((NormInstanceHandle)0);
const NormSessionHandle NORM_SESSION_INVALID = ((NormSessionHandle)0);
@ -10,6 +16,8 @@ const NormNodeId NORM_NODE_NONE = ((NormNodeId)0x00000000);
const NormNodeId NORM_NODE_ANY = ((NormNodeId)0xffffffff);
const NormObjectHandle NORM_OBJECT_INVALID = ((NormObjectHandle)0);
const NormDescriptor NORM_DESCRIPTOR_INVALID = ProtoDispatcher::INVALID_DESCRIPTOR;
/** The "NormInstance" class is a C++ helper class that keeps
* state for an instance of the NORM API. It acts as a
* "go between" the API's procedural function calls and
@ -27,7 +35,7 @@ class NormInstance : public NormController
class NormServerNode* server,
class NormObject* object);
bool Startup();
bool Startup(bool priorityBoost = false);
void Shutdown();
bool WaitForEvent();
@ -250,9 +258,38 @@ void NormInstance::Notify(NormController::Event event,
{
char fileName[PATH_MAX];
strncpy(fileName, rx_cache_path, PATH_MAX);
strcat(fileName, "normTempXXXXXX");
size_t catMax = strlen(fileName);
if (catMax > PATH_MAX)
catMax = 0;
else
catMax = PATH_MAX - catMax;
strncat(fileName, "normTempXXXXXX", catMax);
#ifdef WIN32
#ifdef _WIN32_WCE
bool tempFileOK = false;
for (int i = 0; i < 255; i++)
{
strncpy(fileName, rx_cache_path, PATH_MAX);
catMax = strlen(fileName);
if (catMax > PATH_MAX)
catMax = 0;
else
catMax = PATH_MAX - catMax;
strncat(fileName, "normTempXXXXXX", catMax);
char tempName[16];
sprintf(tempName, "normTemp%06u", i);
strcat(fileName, tempName);
if(!NormFile::IsLocked(fileName))
{
tempFileOK = true;
break;
}
}
if (!tempFileOK)
#else
if (!_mktemp(fileName))
#endif // if/else _WIN32_WCE
#else
int fd = mkstemp(fileName);
if (fd >= 0)
@ -263,7 +300,7 @@ void NormInstance::Notify(NormController::Event event,
#endif // if/else WIN32
{
DMSG(0, "NormInstance::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n",
strerror(errno));
GetErrorString());
}
if (!static_cast<NormFileObject*>(object)->Accept(fileName))
{
@ -401,6 +438,11 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
// reset update event notification
((NormObject*)n->event.object)->SetNotifyOnUpdate(true);
break;
case NORM_TX_QUEUE_VACANCY:
if (NULL != n->event.object)
static_cast<NormStreamObject*>((NormObject*)n->event.object)->ResetPostedTxQueueVacancy();
// (TBD) support session-level queue vacancy notify
break;
default:
break;
}
@ -441,7 +483,7 @@ bool NormInstance::WaitForEvent()
} // end NormInstance::WaitForEvent()
bool NormInstance::Startup()
bool NormInstance::Startup(bool priorityBoost)
{
// 1) Create descriptor to use for event notification
#ifdef WIN32
@ -469,7 +511,7 @@ bool NormInstance::Startup()
}
#endif // if/else WIN32/UNIX
// 2) Start thread
return dispatcher.StartThread();
return dispatcher.StartThread(priorityBoost);
} // end NormInstance::Startup()
void NormInstance::Shutdown()
@ -554,12 +596,12 @@ void NormInstance::Shutdown()
/** NORM API Initialization */
NormInstanceHandle NormCreateInstance()
NormInstanceHandle NormCreateInstance(bool priorityBoost)
{
NormInstance* normInstance = new NormInstance;
if (normInstance)
{
if (normInstance->Startup())
if (normInstance->Startup(priorityBoost))
return ((NormInstanceHandle)normInstance);
else
delete normInstance;
@ -582,6 +624,15 @@ bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
return false;
} // end NormSetCacheDirectory()
NormDescriptor NormGetDescriptor(NormInstanceHandle instanceHandle)
{
NormInstance* instance = (NormInstance*)instanceHandle;
if (instance)
return (instance->GetDescriptor());
else
return NORM_DESCRIPTOR_INVALID;
} // end NormGetDescriptor()
bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent)
{
bool result = false;
@ -636,6 +687,37 @@ void NormDestroySession(NormSessionHandle sessionHandle)
}
} // end NormDestroySession()
void NormSetUserData(NormSessionHandle sessionHandle, const void* userData)
{
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
if (instance)
{
if (instance->dispatcher.SuspendThread())
{
NormSession* session = (NormSession*)sessionHandle;
if (session) session->SetUserData(userData);
instance->dispatcher.ResumeThread();
}
}
} // end NormSetUserData()
const void* NormGetUserData(NormSessionHandle sessionHandle)
{
const void* userData = NULL;
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
if (instance)
{
if (instance->dispatcher.SuspendThread())
{
NormSession* session = (NormSession*)sessionHandle;
if (session)
userData = session->GetUserData();
instance->dispatcher.ResumeThread();
}
}
return userData;
} // end NormGetUserData()
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
{
NormSession* session = (NormSession*)sessionHandle;
@ -645,6 +727,21 @@ NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
return NORM_NODE_NONE;
} // end NormGetLocalNodeId()
void NormSetTxPort(NormSessionHandle sessionHandle,
unsigned short txPort)
{
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
if (instance)
{
if (instance->dispatcher.SuspendThread())
{
NormSession* session = (NormSession*)sessionHandle;
if (session) session->SetTxPort(txPort);
instance->dispatcher.ResumeThread();
}
}
} // end NormSetTxPort()
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
const char* interfaceName)
{
@ -774,6 +871,21 @@ void NormSetTransmitRate(NormSessionHandle sessionHandle,
}
} // end NormSetTransmitRate()
bool NormSetTxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize)
{
bool result = false;
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
if (instance && instance->dispatcher.SuspendThread())
{
NormSession* session = (NormSession*)sessionHandle;
if (session)
result = session->SetTxSocketBuffer(bufferSize);
instance->dispatcher.ResumeThread();
}
return result;
} // end NormSetTxSocketBuffer()
void NormSetCongestionControl(NormSessionHandle sessionHandle, bool enable)
{
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
@ -936,7 +1048,13 @@ void NormStreamFlush(NormObjectHandle streamHandle,
{
NormStreamObject* stream =
static_cast<NormStreamObject*>((NormObject*)streamHandle);
if (stream) stream->Flush(eom);
if (stream)
{
NormStreamObject::FlushMode saveFlushMode = stream->GetFlushMode();
stream->SetFlushMode((NormStreamObject::FlushMode)flushMode);
stream->Flush(eom);
stream->SetFlushMode(saveFlushMode);
}
instance->dispatcher.ResumeThread();
}
} // end NormStreamFlush()
@ -1036,6 +1154,21 @@ void NormStopReceiver(NormSessionHandle sessionHandle)
}
} // end NormStopReceiver()
bool NormSetRxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize)
{
bool result = false;
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
if (instance && instance->dispatcher.SuspendThread())
{
NormSession* session = (NormSession*)sessionHandle;
if (session)
result = session->SetRxSocketBuffer(bufferSize);
instance->dispatcher.ResumeThread();
}
return result;
} // end NormSetRxSocketBuffer()
void NormSetSilentReceiver(NormSessionHandle sessionHandle,
bool silent)
{
@ -1293,6 +1426,37 @@ NormNodeId NormNodeGetId(NormNodeHandle nodeHandle)
return NORM_NODE_NONE;
} // end NormNodeGetId()
bool NormNodeGetAddress(NormNodeHandle nodeHandle,
char* addrBuffer,
unsigned int* bufferLen,
unsigned short* port)
{
bool result = false;
if (NORM_NODE_INVALID != nodeHandle)
{
NormInstance* instance = NormInstance::GetInstanceFromNode(nodeHandle);
if (instance && instance->dispatcher.SuspendThread())
{
NormNode* node = (NormNode*)nodeHandle;
const ProtoAddress& nodeAddr = node->GetAddress();
unsigned int addrLen = nodeAddr.GetLength();
if (addrBuffer && bufferLen && (addrLen <= *bufferLen))
{
memcpy(addrBuffer, nodeAddr.GetRawHostAddress(), addrLen);
result = true;
}
else if (NULL == addrBuffer)
{
result = true; // just a query for addrLen and/or port
}
if (bufferLen) *bufferLen = addrLen;
if (port) *port = nodeAddr.GetPort();
instance->dispatcher.ResumeThread();
}
}
return result;
} // end NormNodeGetId()
void NormNodeRetain(NormNodeHandle nodeHandle)
{
if (NORM_NODE_INVALID != nodeHandle)

View File

@ -6,8 +6,13 @@
#include <windows.h>
#endif // WIN32
#ifdef _WIN32_WCE
#include <stdio.h>
//typedef fpos_t off_t;
typedef long off_t;
#else
#include <sys/types.h> // for "off_t" type
#endif // if/else _WIN32_WCE
////////////////////////////////////////////////////////////
// IMPORTANT NOTICE
// The NORM API is _very_ much in a developmental phase
@ -100,7 +105,7 @@ typedef struct
/** NORM API General Initialization and Operation Functions */
NormInstanceHandle NormCreateInstance();
NormInstanceHandle NormCreateInstance(bool priorityBoost = false);
void NormDestroyInstance(NormInstanceHandle instanceHandle);
@ -125,6 +130,7 @@ typedef HANDLE NormDescriptor;
#else
typedef int NormDescriptor;
#endif // if/else WIN32/UNIX
extern const NormDescriptor NORM_DESCRIPTOR_INVALID;
NormDescriptor NormGetDescriptor(NormInstanceHandle instanceHandle);
/** NORM Session Creation and Control Functions */
@ -136,8 +142,15 @@ NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
void NormDestroySession(NormSessionHandle sessionHandle);
void NormSetUserData(NormSessionHandle sessionHandle, const void* userData);
const void* NormGetUserData(NormSessionHandle sessionHandle);
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
void NormSetTxPort(NormSessionHandle sessionHandle,
unsigned short txPortNumber);
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
const char* interfaceName);
@ -169,6 +182,9 @@ void NormStopSender(NormSessionHandle sessionHandle);
void NormSetTransmitRate(NormSessionHandle sessionHandle,
double bitsPerSecond);
bool NormSetTxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize);
void NormSetCongestionControl(NormSessionHandle sessionHandle,
bool state);
@ -231,6 +247,9 @@ bool NormStartReceiver(NormSessionHandle sessionHandle,
void NormStopReceiver(NormSessionHandle sessionHandle);
bool NormSetRxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize);
void NormSetSilentReceiver(NormSessionHandle sessionHandle,
bool silent);
@ -302,6 +321,11 @@ NormNodeHandle NormObjectGetSender(NormObjectHandle objectHandle);
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle);
bool NormNodeGetAddress(NormNodeHandle nodeHandle,
char* addrBuffer,
unsigned int* bufferLen,
unsigned short* port = (unsigned short*)0);
void NormNodeRetain(NormNodeHandle nodeHandle);
void NormNodeRelease(NormNodeHandle nodeHandle);

View File

@ -6,8 +6,6 @@
#include "normPostProcess.h"
#include <stdio.h> // for stdout/stderr printouts
#include <signal.h> // for SIGTERM/SIGINT handling
#include <errno.h>
#include <stdlib.h>
#include <ctype.h> // for "isspace()"
@ -419,7 +417,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
if (!(address = new char[len+1]))
{
DMSG(0, "NormApp::OnCommand(address) allocation error:%s\n",
strerror(errno));
GetErrorString());
return false;
}
strcpy(address, val);
@ -526,7 +524,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(input = fopen(val, "rb")))
{
DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
input_index = input_length = 0;
@ -546,7 +544,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(output = fopen(val, "wb")))
{
DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
output_messaging = false;
@ -562,7 +560,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(input = fopen(val, "rb")))
{
DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
input_index = input_length = 0;
@ -582,7 +580,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(output = fopen(val, "wb")))
{
DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
output_messaging = true;
@ -641,7 +639,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
if (!(rx_cache_path = new char[length]))
{
DMSG(0, "NormApp::OnCommand(rxcachedir) alloc error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
strcpy(rx_cache_path, val);
@ -979,6 +977,7 @@ void NormApp::OnInputReady()
}
else if (ferror(input))
{
#ifndef WIN32 // no Win32 stream support yet
switch (errno)
{
case EINTR:
@ -988,9 +987,10 @@ void NormApp::OnInputReady()
inputStarved = true;
break;
default:
DMSG(0, "norm: input error:%s\n", strerror(errno));
DMSG(0, "norm: input error:%s\n", GetErrorString());
break;
}
#endif // !WIN32
clearerr(input);
}
}
@ -1123,9 +1123,37 @@ void NormApp::Notify(NormController::Event event,
// (TBD) Manage recv file name collisions, etc ...
char fileName[PATH_MAX];
strcpy(fileName, rx_cache_path);
size_t catMax = strlen(fileName);
if (catMax > PATH_MAX)
catMax = 0;
else
catMax = PATH_MAX - catMax;
strcat(fileName, "normTempXXXXXX");
#ifdef WIN32
#ifdef _WIN32_WCE
bool tempFileOK = false;
for (int i = 0; i < 255; i++)
{
strncpy(fileName, rx_cache_path, PATH_MAX);
catMax = strlen(fileName);
if (catMax > PATH_MAX)
catMax = 0;
else
catMax = PATH_MAX - catMax;
strncat(fileName, "normTempXXXXXX", catMax);
char tempName[16];
sprintf(tempName, "normTemp%06u", i);
strcat(fileName, tempName);
if(!NormFile::IsLocked(fileName))
{
tempFileOK = true;
break;
}
}
if (!tempFileOK)
#else
if (!_mktemp(fileName))
#endif // if/else _WIN32_WCE
#else
int fd = mkstemp(fileName);
if (fd >= 0)
@ -1136,7 +1164,7 @@ void NormApp::Notify(NormController::Event event,
#endif // if/else WIN32
{
DMSG(0, "NormApp::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n",
strerror(errno));
GetErrorString());
}
if (!static_cast<NormFileObject*>(object)->Accept(fileName))
{
@ -1305,14 +1333,16 @@ void NormApp::Notify(NormController::Event event,
{
if (ferror(output))
{
#ifndef WIN32 // no stream support in this app for Win32
if (EINTR == errno)
{
clearerr(output);
continue;
}
else
#endif // !WIN32
{
DMSG(0, "norm: output error:%s\n", strerror(errno));
DMSG(0, "norm: output error:%s\n", GetErrorString());
clearerr(output);
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,208 +0,0 @@
#ifndef _NORM_BITMASK_
#define _NORM_BITMASK_
#include "protokit.h" // for PROTO_DEBUG stuff
#include <string.h> // for memset()
#include <stdio.h> // for fprintf()
/***************************************************************
* This class also provides space-efficient binary storage.
* It's pretty much just a flat-indexed array of bits, but
* keeps some state to be relatively efficient for various
* operations.
*/
class NormBitmask
{
// Methods
public:
NormBitmask();
~NormBitmask();
bool Init(UINT32 numBits);
void Destroy();
UINT32 Size() {return num_bits;}
void Clear() // set to all zero's
{
memset(mask, 0, mask_len);
first_set = num_bits;
};
void Reset() // set to all one's
{
memset(mask, 0xff, (mask_len-1));
mask[mask_len-1] = 0x00ff << ((8 - (num_bits & 0x07)) & 0x07);
first_set = 0;
}
bool IsSet() const {return (first_set < num_bits);}
bool GetFirstSet(UINT32& index) const
{
index = first_set;
return IsSet();
}
bool GetLastSet(UINT32& index) const
{
index = num_bits - 1;
return GetPrevSet(index);
}
bool Test(UINT32 index) const
{
return ((index < num_bits) ?
(0 != (mask[(index >> 3)] & (0x80 >> (index & 0x07)))) :
false);
}
bool CanSet(UINT32 index) const
{return (index < num_bits);}
bool Set(UINT32 index)
{
if (index < num_bits)
{
mask[(index >> 3)] |= (0x80 >> (index & 0x07));
(index < first_set) ? (first_set = index) : 0;
return true;
}
else
{
return false;
}
}
bool Unset(UINT32 index)
{
if (index < num_bits)
{
mask[(index >> 3)] &= ~(0x80 >> (index & 0x07));
(index == first_set) ? first_set = GetNextSet(first_set) ? first_set : num_bits : 0;
}
return true;
}
bool Invert(UINT32 index)
{return (Test(index) ? Unset(index) : Set(index));}
bool SetBits(UINT32 baseIndex, UINT32 count);
bool UnsetBits(UINT32 baseIndex, UINT32 count);
bool GetNextSet(UINT32& index) const;
bool GetPrevSet(UINT32& index) const;
bool GetNextUnset(UINT32& index) const;
bool Copy(const NormBitmask &b); // this = b
bool Add(const NormBitmask & b); // this = this | b
bool Subtract(const NormBitmask & b); // this = this & ~b
bool XCopy(const NormBitmask & b); // this = ~this & b
bool Multiply(const NormBitmask & b); // this = this & b
bool Xor(const NormBitmask & b); // this = this ^ b
void Display(FILE* stream);
// Members
private:
unsigned char* mask;
UINT32 mask_len;
UINT32 num_bits;
UINT32 first_set; // index of lowest _set_ bit
}; // end class NormBitmask
/***************************************************************
* This class also provides space-efficient binary storage.
* More than just a flat-indexed array of bits, this
* class can also automatically act as a sliding
* window buffer as long as the range of set bit
* indexes fall within the number of storage bits
* for which the class initialized.
*/
class NormSlidingMask
{
public:
NormSlidingMask();
~NormSlidingMask();
const char* GetMask() const {return (const char*)mask;}
bool Init(INT32 numBits, UINT32 rangeMax);
void Destroy();
INT32 Size() const {return num_bits;}
void Clear()
{
memset(mask, 0, mask_len);
start = end = num_bits;
offset = 0;
}
void Reset(UINT32 index = 0)
{
ASSERT(num_bits);
memset(mask, 0xff, mask_len);
mask[mask_len-1] = 0x00ff << ((8 - (num_bits & 0x07)) & 0x07);
start = 0;
end = num_bits - 1;
offset = index;
}
bool IsSet() const {return (start < num_bits);}
bool GetFirstSet(UINT32& index) const
{
index = offset;
return IsSet();
}
bool GetLastSet(UINT32& index) const
{
INT32 n = end - start;
n = (n < 0) ? (n + num_bits) : n;
index = offset + n;
return IsSet();
}
bool Test(UINT32 index) const;
bool CanSet(UINT32 index) const;
bool Set(UINT32 index);
bool Unset(UINT32 index);
bool Invert(UINT32 index)
{return (Test(index) ? Unset(index): Set(index));}
bool SetBits(UINT32 index, INT32 count);
bool UnsetBits(UINT32 index, INT32 count);
// These return "false" when finding nothing
bool GetNextSet(UINT32& index) const;
bool GetPrevSet(UINT32& index) const;
bool Copy(const NormSlidingMask& b); // this = b
bool Add(const NormSlidingMask & b); // this = this | b
bool Subtract(const NormSlidingMask & b); // this = this & ~b
bool XCopy(const NormSlidingMask & b); // this = ~this & b
bool Multiply(const NormSlidingMask & b); // this = this & b
bool Xor(const NormSlidingMask & b); // this = this ^ b
void Display(FILE* stream);
void Debug(INT32 theCount);
private:
// Calculate "circular" delta between two indices
INT32 Delta(UINT32 a, UINT32 b) const
{
INT32 result = a - b;
return ((0 == (result & range_sign)) ?
(result & range_mask) :
(((result != range_sign) || (a < b)) ?
(result | ~range_mask) : result));
}
unsigned char* mask;
UINT32 mask_len;
UINT32 range_mask;
INT32 range_sign;
INT32 num_bits;
INT32 start;
INT32 end;
UINT32 offset;
}; // end class NormSlidingMask
#endif // _NORM_BITMASK_

View File

@ -33,7 +33,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "normEncoder.h"
#include "galois.h" // for Galois math routines
@ -78,7 +77,7 @@ bool NormEncoder::Init(int numParity, int vecSizeMax)
if(!(scratch = new unsigned char[vecSizeMax]))
{
DMSG(0, "NormEncoder: Error allocating memory for encoder scratch space: %s\n",
strerror(errno));
GetErrorString());
Destroy();
return false;
}
@ -110,14 +109,14 @@ bool NormEncoder::CreateGeneratorPolynomial()
if(!(genPoly = new unsigned char[npar+1]))
{
DMSG(0, "NormEncoder: Error allocating memory for generator polynomial: %s\n",
strerror(errno));
GetErrorString());
return false;
}
/* Allocate memory for temporary polynomial arrays */
if(!(tp = new unsigned char[2*degree]))
{
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno));
GetErrorString());
delete genPoly;
return false;
}
@ -126,7 +125,7 @@ bool NormEncoder::CreateGeneratorPolynomial()
delete tp;
delete genPoly;
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno));
GetErrorString());
return false;
}
if(!(tp2 = new unsigned char[2*degree]))
@ -135,7 +134,7 @@ bool NormEncoder::CreateGeneratorPolynomial()
delete tp;
delete genPoly;
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno));
GetErrorString());
return false;
}
// multiply (x + a^n) for n = 1 to npar
@ -247,7 +246,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(Lambda = new unsigned char[2*npar]))
{
DMSG(0, "NormDecoder: Error allocating memory for Lambda: %s\n",
strerror(errno));
GetErrorString());
return(false);
}
@ -255,7 +254,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(sVec = new unsigned char*[npar]))
{
DMSG(0, "NormDecoder: Error allocating memory for sVec ptr: %s\n",
strerror(errno));
GetErrorString());
Destroy();
return(false);
}
@ -265,7 +264,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(sVec[i] = new unsigned char[vecSizeMax]))
{
DMSG(0, "NormDecoder: Error allocating memory for new sVec: %s\n",
strerror(errno));
GetErrorString());
Destroy();
return(false);
}
@ -275,7 +274,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(oVec = new unsigned char*[npar]))
{
DMSG(0, "NormDecoder: Error allocating memory for new oVec ptr: %s\n",
strerror(errno));
GetErrorString());
Destroy();
return(false);
}
@ -285,7 +284,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(oVec[i] = new unsigned char[vecSizeMax]))
{
DMSG(0, "NormDecoder: Error allocating memory for new oVec: %s",
strerror(errno));
GetErrorString());
Destroy();
return(false);
}
@ -294,7 +293,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if (!(scratch = new unsigned char[vecSizeMax]))
{
DMSG(0, "NormDecoder: Error allocating memory for scratch space: %s",
strerror(errno));
GetErrorString());
}
memset(scratch, 0, vecSizeMax*sizeof(unsigned char));
return(true);

View File

@ -1,11 +1,13 @@
#include "normFile.h"
#include <string.h> // for strerror()
#include <errno.h> // for errno
#include <stdio.h> // for rename()
#ifdef WIN32
#ifndef _WIN32_WCE
#include <direct.h>
#include <share.h>
#include <io.h>
#endif // !_WIN32_WCE
#else
#include <unistd.h>
// Most don't have the dirfd() function
@ -14,8 +16,18 @@ static inline int dirfd(DIR *dir) {return (dir->dd_fd);}
#endif // HAVE_DIRFD
#endif // if/else WIN32
#ifndef _WIN32_WCE
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif // !_WIN32_WCE
NormFile::NormFile()
#ifdef _WIN32_WCE
: file_ptr(NULL)
#else
: fd(-1)
#endif // if/else _WIN32_WCE
{
}
@ -24,6 +36,7 @@ NormFile::~NormFile()
if (IsOpen()) Close();
} // end NormFile::~NormFile()
// This should be called with a full path only!
bool NormFile::Open(const char* thePath, int theFlags)
{
@ -57,13 +70,25 @@ bool NormFile::Open(const char* thePath, int theFlags)
ptr = strchr(ptr, PROTO_PATH_DELIMITER);
if (ptr) *ptr = '\0';
#ifdef WIN32
#ifdef _WIN32_WCE
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t pathLen = strlen(tempPath) + 1;
if (pathLen > MAX_PATH) pathLen = MAX_PATH;
mbstowcs(wideBuffer, tempPath, pathLen);
if (!CreateDirectory(wideBuffer, NULL))
#else
if (!CreateDirectory(tempPath, NULL))
#endif // if/else _UNICODE
#else
if (mkdir(tempPath))
#endif // if/else _WIN32_WCE
#else
if (mkdir(tempPath, 0755))
#endif // if/else WIN32/UNIX
{
DMSG(0, "NormFile::Open() mkdir(%s) error: %s\n",
tempPath, strerror(errno));
tempPath, GetErrorString());
return false;
}
if (ptr) *ptr++ = PROTO_PATH_DELIMITER;
@ -71,13 +96,21 @@ bool NormFile::Open(const char* thePath, int theFlags)
}
#ifdef WIN32
// Make sure we're in binary mode (important for WIN32)
theFlags |= _O_BINARY;
theFlags |= O_BINARY;
#ifdef _WIN32_WCE
if (theFlags & O_RDONLY)
file_ptr = fopen(thePath, "r");
else
file_ptr = fopen(thePath, "w+");
if (NULL != file_ptr)
#else
// Allow sharing of read-only files but not of files being written
if (theFlags & _O_RDONLY)
if (theFlags & O_RDONLY)
fd = _sopen(thePath, theFlags, _SH_DENYNO);
else
fd = _open(thePath, theFlags, 0640);
if(fd >= 0)
#endif // if/else _WIN32_WCE
{
offset = 0;
flags = theFlags;
@ -85,7 +118,7 @@ bool NormFile::Open(const char* thePath, int theFlags)
}
else
{
DMSG(0, "Error opening file \"%s\": %s\n", thePath, strerror(errno));
DMSG(0, "Error opening file \"%s\": %s\n", thePath, GetErrorString());
flags = 0;
return false;
}
@ -98,7 +131,7 @@ bool NormFile::Open(const char* thePath, int theFlags)
else
{
DMSG(0, "norm: Error opening file \"%s\": %s\n",
thePath, strerror(errno));
thePath, GetErrorString());
return false;
}
#endif // if/else WIN32
@ -109,11 +142,18 @@ void NormFile::Close()
if (IsOpen())
{
#ifdef WIN32
#ifdef _WIN32_WCE
fclose(file_ptr);
file_ptr = NULL;
#else
_close(fd);
fd = -1;
#endif // if/else _WIN32_WCE
#else
close(fd);
#endif // if/else WIN32
fd = -1;
#endif // if/else WIN32
}
} // end NormFile::Close()
@ -167,11 +207,27 @@ bool NormFile::Rename(const char* oldName, const char* newName)
// In Win32, the new file can't already exist
if (NormFile::Exists(newName))
{
#ifdef _WIN32_WCE
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t pathLen = strlen(newName) + 1;
if (pathLen > MAX_PATH) pathLen = MAX_PATH;
mbstowcs(wideBuffer, newName, pathLen);
if (0 == DeleteFile(wideBuffer))
#else
if (0 == DeleteFile(newName))
#endif // if/else _UNICODE
{
DMSG(0, "NormFile::Rename() DeleteFile() error: %s\n", GetErrorString());
return false;
}
#else
if (0 != _unlink(newName))
{
DMSG(0, "NormFile::Rename() _unlink() error: %s\n", GetErrorString());
return false;
}
#endif // if/else _WIN32_WCE
}
// In Win32, the old file can't be open
int oldFlags = 0;
@ -209,7 +265,19 @@ bool NormFile::Rename(const char* oldName, const char* newName)
ptr = strchr(ptr, PROTO_PATH_DELIMITER);
if (ptr) *ptr = '\0';
#ifdef WIN32
if (0 != _mkdir(tempPath))
#ifdef _WIN32_WCE
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t pathLen = strlen(tempPath) + 1;
if (pathLen > MAX_PATH) pathLen = MAX_PATH;
mbstowcs(wideBuffer, tempPath, pathLen);
if (!CreateDirectory(wideBuffer, NULL))
#else
if (!CreateDirectory(tempPath, NULL))
#endif // if/else _UNICODE
#else
if (0 != mkdir(tempPath))
#endif // if/else _WIN32_WCE
#else
if (mkdir(tempPath, 0755))
#endif // if/else WIN32/UNIX
@ -220,10 +288,23 @@ bool NormFile::Rename(const char* oldName, const char* newName)
}
if (ptr) *ptr++ = PROTO_PATH_DELIMITER;
}
#ifdef _WIN32_WCE
#ifdef _UNICODE
wchar_t wideOldName[MAX_PATH];
wchar_t wideNewName[MAX_PATH];
mbstowcs(wideOldName, oldName, MAX_PATH);
mbstowcs(wideNewName, newName, MAX_PATH);
if (!MoveFile(wideOldName, wideNewName))
#else
if (!MoveFile(oldName, newName))
#endif // if/else _UNICODE
{
DMSG(0, "NormFile::Rename() MoveFile() error: %s\n", GetErrorString());
#else
if (rename(oldName, newName))
{
DMSG(0, "NormFile::Rename() rename() error: %s\n", strerror(errno));
DMSG(0, "NormFile::Rename() rename() error: %s\n", GetErrorString());
#endif // if/else _WIN32_WCE
#ifdef WIN32
if (oldFlags)
{
@ -255,7 +336,11 @@ int NormFile::Read(char* buffer, int len)
{
ASSERT(IsOpen());
#ifdef WIN32
#ifdef _WIN32_WCE
size_t result = fread(buffer, 1, len, file_ptr);
#else
int result = _read(fd, buffer, len);
#endif // if/else _WIN32_WCE
#else
int result = read(fd, buffer, len);
#endif // if/else WIN32
@ -267,7 +352,11 @@ int NormFile::Write(const char* buffer, int len)
{
ASSERT(IsOpen());
#ifdef WIN32
#ifdef _WIN32_WCE
size_t result = fwrite(buffer, 1, len, file_ptr);
#else
int result = _write(fd, buffer, len);
#endif // if/else _WIN32_WCE
#else
int result = write(fd, buffer, len);
#endif // if/else WIN32
@ -279,13 +368,18 @@ bool NormFile::Seek(off_t theOffset)
{
ASSERT(IsOpen());
#ifdef WIN32
#ifdef _WIN32_WCE
// (TBD) properly support big files on WinCE
off_t result = fseek(file_ptr, (long)theOffset, SEEK_SET);
#else
off_t result = _lseek(fd, theOffset, SEEK_SET);
#endif // if/else _WIN32_WCE
#else
off_t result = lseek(fd, theOffset, SEEK_SET);
#endif // if/else WIN32
if (result == (off_t)-1)
{
DMSG(0, "NormFile::Seek() lseek() error: %s", strerror(errno));
DMSG(0, "NormFile::Seek() lseek() error: %s", GetErrorString());
return false;
}
else
@ -298,6 +392,10 @@ bool NormFile::Seek(off_t theOffset)
off_t NormFile::GetSize() const
{
ASSERT(IsOpen());
#ifdef _WIN32_WCE
DWORD fileSize = GetFileSize(_fileno(file_ptr), NULL);
return ((off_t)fileSize);
#else
#ifdef WIN32
struct _stat info;
int result = _fstat(fd, &info);
@ -307,13 +405,14 @@ off_t NormFile::GetSize() const
#endif // if/else WIN32
if (result)
{
DMSG(0, "Error getting file size: %s\n", strerror(errno));
DMSG(0, "Error getting file size: %s\n", GetErrorString());
return 0;
}
else
{
return info.st_size;
}
#endif // if/else _WIN32_WCE
} // end NormFile::GetSize()
@ -337,7 +436,11 @@ bool NormDirectoryIterator::Open(const char *thePath)
{
if (current) Close();
#ifdef WIN32
#ifdef _WIN32_WCE
if (thePath && !NormFile::Exists(thePath))
#else
if (thePath && _access(thePath, 0))
#endif // if/else _WIN32_WCE
#else
if (thePath && access(thePath, X_OK))
#endif // if/else WIN32
@ -401,8 +504,15 @@ bool NormDirectoryIterator::GetNextFile(char* fileName)
// Construct search string
current->GetFullName(fileName);
strcat(fileName, "\\*");
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, fileName, MAX_PATH);
if ((HANDLE)-1 ==
(current->hSearch = FindFirstFile(fileName, &findData)) )
(current->hSearch = FindFirstFile(wideBuffer, &findData)))
#else
if ((HANDLE)-1 ==
(current->hSearch = FindFirstFile(fileName, &findData)))
#endif // if/else _UNICODE
success = false;
else
success = true;
@ -415,11 +525,21 @@ bool NormDirectoryIterator::GetNextFile(char* fileName)
// Do we have a candidate file?
if (success)
{
#ifdef _UNICODE
char cFileName[MAX_PATH];
wcstombs(cFileName, findData.cFileName, MAX_PATH);
char* ptr = strrchr(cFileName, PROTO_PATH_DELIMITER);
#else
char* ptr = strrchr(findData.cFileName, PROTO_PATH_DELIMITER);
#endif // if/else _UNICODE
if (ptr)
ptr += 1;
else
#ifdef _UNICODE
ptr = cFileName;
#else
ptr = findData.cFileName;
#endif // if/else _UNICODE
// Skip "." and ".." directories
if (ptr[0] == '.')
@ -584,7 +704,13 @@ bool NormDirectoryIterator::NormDirectory::Open()
int len = MIN(PATH_MAX, strlen(fullName));
if (PROTO_PATH_DELIMITER == fullName[len-1]) fullName[len-1] = '\0';
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, fullName, MAX_PATH);
DWORD attr = GetFileAttributes(wideBuffer);
#else
DWORD attr = GetFileAttributes(fullName);
#endif // if/else _UNICODE
if (0xFFFFFFFF == attr)
return false;
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
@ -637,7 +763,13 @@ void NormDirectoryIterator::NormDirectory::RecursiveCatName(char* ptr)
NormFile::Type NormFile::GetType(const char* path)
{
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, path, MAX_PATH);
DWORD attr = GetFileAttributes(wideBuffer);
#else
DWORD attr = GetFileAttributes(path);
#endif // if/else _UNICODE
if (0xFFFFFFFF == attr)
return INVALID; // error
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
@ -657,6 +789,24 @@ NormFile::Type NormFile::GetType(const char* path)
off_t NormFile::GetSize(const char* path)
{
#ifdef _WIN32_WCE
WIN32_FIND_DATA findData;
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, path, MAX_PATH);
if (INVALID_HANDLE_VALUE != FindFirstFile(wideBuffer, &findData))
#else
if (INVALID_HANDLE_VALUE != FindFirstFile(path, &findData))
#endif // if/else _UNICODE
{
return ((off_t)findData.nFileSizeLow); // (TBD) support big files
}
else
{
DMSG(0, "Error getting file size: %s\n", GetErrorString());
return 0;
}
#else
#ifdef WIN32
struct _stat info;
int result = _stat(path, &info);
@ -666,17 +816,49 @@ off_t NormFile::GetSize(const char* path)
#endif // if/else WIN32
if (result)
{
//DMSG(0, "Error getting file size: %s\n", strerror(errno));
//DMSG(0, "Error getting file size: %s\n", GetErrorString());
return 0;
}
else
{
return info.st_size;
}
#endif // if/else _WIN32_WCE
} // end NormFile::GetSize()
time_t NormFile::GetUpdateTime(const char* path)
{
#ifdef _WIN32_WCE
WIN32_FIND_DATA findData;
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, path, MAX_PATH);
if (INVALID_HANDLE_VALUE != FindFirstFile(wideBuffer, &findData))
#else
if (INVALID_HANDLE_VALUE != FindFirstFile(path, &findData))
#endif // if/else _UNICODE
{
ULARGE_INTEGER ctime = {findData.ftCreationTime.dwLowDateTime,
findData.ftCreationTime.dwHighDateTime};
ULARGE_INTEGER atime = {findData.ftLastAccessTime.dwLowDateTime,
findData.ftLastAccessTime.dwHighDateTime};
ULARGE_INTEGER mtime = {findData.ftLastWriteTime.dwLowDateTime,
findData.ftLastWriteTime.dwHighDateTime};
if (ctime.QuadPart < atime.QuadPart) ctime = atime;
if (ctime.QuadPart < mtime.QuadPart) ctime = mtime;
const ULARGE_INTEGER epochTime = {0xD53E8000, 0x019DB1DE};
ctime.QuadPart -= epochTime.QuadPart;
// Convert sytem time to seconds
ctime.QuadPart /= 10000000;
return ctime.LowPart;
}
else
{
DMSG(0, "Error getting file size: %s\n", GetErrorString());
return 0;
}
#else
#ifdef WIN32
struct _stat info;
int result = _stat(path, &info);
@ -699,6 +881,7 @@ time_t NormFile::GetUpdateTime(const char* path)
return info.st_ctime;
#endif // if/else WIN32
}
#endif // if/else _WIN32_WCE
} // end NormFile::GetUpdateTime()
bool NormFile::IsLocked(const char* path)
@ -707,7 +890,7 @@ bool NormFile::IsLocked(const char* path)
if (!Exists(path)) return false;
NormFile testFile;
#ifdef WIN32
if(!testFile.Open(path, _O_WRONLY | _O_CREAT))
if(!testFile.Open(path, O_WRONLY | O_CREAT))
#else
if(!testFile.Open(path, O_WRONLY | O_CREAT))
#endif // if/else WIN32
@ -735,19 +918,35 @@ bool NormFile::Unlink(const char* path)
{
return false;
}
#ifdef WIN32
else if (_unlink(path))
#ifdef _WIN32_WCE
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
mbstowcs(wideBuffer, path, MAX_PATH);
if (0 == DeleteFile(wideBuffer))
#else
else if (unlink(path))
#endif // if/else WIN32
if (0 == DeleteFile(path))
#endif // if/else _UNICODE
{
//DMSG(0, "NormFile::Unlink() unlink error: %s\n", strerror(errno));
DMSG(0, "NormFile::Unlink() DeletFile() error: %s\n", GetErrorString());
return false;
}
#else
#ifdef WIN32
if (_unlink(path))
#else
if (unlink(path))
#endif // if/else WIN32
{
DMSG(0, "NormFile::Unlink() unlink error: %s\n", GetErrorString());
return false;
}
#endif // if/else _WIN32_WCE
else
{
return true;
}
} // end NormFile::Unlink()
NormFileList::NormFileList()
@ -810,7 +1009,7 @@ bool NormFileList::Append(const char* path)
else
{
DMSG(0, "NormFileList::Append() Error creating file/directory item: %s\n",
strerror(errno));
GetErrorString());
return false;
}
} // end NormFileList::Append()

View File

@ -7,19 +7,40 @@
// class is provided to manage a list of files.
#ifdef WIN32
#include <io.h>
//#include <io.h>
#else
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif // if/else WIN32
#include <fcntl.h>
#ifdef _WIN32_WCE
#include <stdio.h>
typedef fpos_t off_t;
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif // if/else _WIN32_WCE
// From PROTOLIB
#include "protokit.h" // for Protolib stuff
// (TBD) Rewrite this implementation to use
// native WIN32 APIs on that platform !!!
#ifdef _WIN32_WCE
// Here we enumerate some stuff to
// make the NormFile work on WinCE
enum
{
O_CREAT = 0x01,
O_TRUNC = 0x02,
O_RDONLY = 0x04,
O_WRONLY = 0x08,
O_RDWR = 0x10
};
#endif // _WIN32_WCE
class NormFile
{
// Methods
@ -33,7 +54,14 @@ class NormFile
bool Rename(const char* oldName, const char* newName);
bool Unlink(const char *path);
void Close();
bool IsOpen() const {return (fd >= 0);}
bool IsOpen() const
{
#ifdef _WIN32_WCE
return (NULL != file_ptr);
#else
return (fd >= 0);
#endif // _WIN32_WCE
}
int Read(char* buffer, int len);
int Write(const char* buffer, int len);
bool Seek(off_t theOffset);
@ -49,7 +77,13 @@ class NormFile
static bool Exists(const char* path)
{
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t count = mbstowcs(wideBuffer, path, strlen(path)+1);
return (0xFFFFFFFF != GetFileAttributes(wideBuffer));
#else
return (0xFFFFFFFF != GetFileAttributes(path));
#endif // if/else _UNICODE
#else
return (0 == access(path, F_OK));
#endif // if/else WIN32
@ -58,7 +92,13 @@ class NormFile
static bool IsWritable(const char* path)
{
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t count = mbstowcs(wideBuffer, path, strlen(path)+1);
DWORD attr = GetFileAttributes(wideBuffer);
#else
DWORD attr = GetFileAttributes(path);
#endif // if/else _UNICODE
return ((0xFFFFFFFF == attr) ?
false : (0 == (attr & FILE_ATTRIBUTE_READONLY)));
#else
@ -69,7 +109,11 @@ class NormFile
// Members
private:
#ifdef _WIN32_WCE
FILE* file_ptr;
#else
int fd;
#endif // if/else _WIN32_WCE
int flags;
off_t offset;
}; // end class NormFile

View File

@ -81,9 +81,16 @@ bool NormMsg::InitFromBuffer(UINT16 msgLength)
DMSG(0, "NormMsg::InitFromBuffer() invalid message type!\n");
return false;
}
ASSERT(msgLength >= header_length);
if (msgLength < header_length)
{
DMSG(0, "NormMsg::InitFromBuffer() invalid message or header length\n");
return false;
}
else
{
length = msgLength;
return true;
}
} // end NormMsg::InitFromBuffer()
bool NormCmdCCMsg::GetCCNode(NormNodeId nodeId,

View File

@ -8,7 +8,13 @@
#include <string.h> // for memcpy(), etc
#include <math.h>
#include <stdlib.h> // for rand(), etc
#ifdef _WIN32_WCE
#include <stdio.h>
typedef fpos_t off_t;
#else
#include <sys/types.h> // for off_t
#endif // if/else _WIN32_WCE
#ifdef SIMULATE
#define SIM_PAYLOAD_MAX (36+8) // MGEN message size + StreamPayloadHeaderLen()
@ -108,10 +114,10 @@ class NormObjectSize
NormObjectSize(const NormObjectSize& size) : msb(size.msb), lsb(size.lsb) {}
NormObjectSize(off_t size)
{
lsb = size & 0x00000000ffffffff;
lsb = (unsigned long)(size & 0x00000000ffffffff);
size >>= 32;
ASSERT(0 == (size & 0xffff0000));
msb = size & 0x0000ffff;
msb = (unsigned short)(size & 0x0000ffff);
msb = 0;
}

View File

@ -2,8 +2,6 @@
#include "normNode.h"
#include "normSession.h"
#include <errno.h>
NormNode::NormNode(class NormSession& theSession, NormNodeId nodeId)
: session(theSession), id(nodeId), reference_count(0),
parent(NULL), right(NULL), left(NULL)
@ -982,7 +980,7 @@ void NormServerNode::HandleObjectMessage(const NormObjectMsg& msg)
if (!(obj = new NormStreamObject(session, this, objectId)))
{
DMSG(0, "NormServerNode::HandleObjectMessage() new NORM_OBJECT_STREAM error: %s\n",
strerror(errno));
GetErrorString());
}
}
else if (msg.FlagIsSet(NormObjectMsg::FLAG_FILE))
@ -994,7 +992,7 @@ void NormServerNode::HandleObjectMessage(const NormObjectMsg& msg)
#endif
{
DMSG(0, "NormServerNode::HandleObjectMessage() new NORM_OBJECT_FILE error: %s\n",
strerror(errno));
GetErrorString());
}
}
else
@ -1002,7 +1000,7 @@ void NormServerNode::HandleObjectMessage(const NormObjectMsg& msg)
if (!(obj = new NormDataObject(session, this, objectId)))
{
DMSG(0, "NormServerNode::HandleObjectMessage() new NORM_OBJECT_DATA error: %s\n",
strerror(errno));
GetErrorString());
}
}
@ -1272,7 +1270,7 @@ NormServerNode::ObjectStatus NormServerNode::GetObjectStatus(const NormObjectId&
else
{
NormObjectId delta = objectId - next_id + 1;
if (delta > NormObjectId((UINT16)rx_pending_mask.Size()))
if (delta > NormObjectId((UINT16)rx_pending_mask.GetSize()))
{
return OBJ_INVALID;
}

View File

@ -385,8 +385,8 @@ class NormServerNode : public NormNode
UINT16 nparity;
NormObjectTable rx_table;
NormSlidingMask rx_pending_mask;
NormSlidingMask rx_repair_mask;
ProtoSlidingMask rx_pending_mask;
ProtoSlidingMask rx_repair_mask;
RepairBoundary repair_boundary;
NormObject::NackingMode default_nacking_mode;
bool unicast_nacks;

View File

@ -1,7 +1,11 @@
#include "normObject.h"
#include "normSession.h"
#include <errno.h>
#ifndef _WIN32_WCE
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif // !_WIN32_WCE
NormObject::NormObject(NormObject::Type theType,
class NormSession& theSession,
@ -1177,8 +1181,6 @@ void NormObject::HandleObjectMessage(const NormObjectMsg& msg,
block->IncrementParityCount();
}
// 3) Decode block if ready and return to pool
if (block->ErasureCount() <= block->ParityCount())
{
@ -2273,7 +2275,7 @@ bool NormStreamObject::Open(UINT32 bufferSize,
Close();
return false;
}
stream_next_id = pending_mask.Size();
stream_next_id = pending_mask.GetSize();
}
stream_sync = false;
@ -2382,7 +2384,7 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
stream_next_id = blockId + 1;
// Handle potential sync block id wrap
NormBlockId delta = stream_next_id - stream_sync_id;
if (delta > NormBlockId(2*pending_mask.Size()))
if (delta > NormBlockId(2*pending_mask.GetSize()))
GetFirstPending(stream_sync_id);
return true;
}
@ -2396,7 +2398,7 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
else
{
NormBlockId delta = blockId - stream_next_id + 1;
if (delta > NormBlockId(pending_mask.Size()))
if (delta > NormBlockId(pending_mask.GetSize()))
{
// Stream broken
//DMSG(0, "NormObject::StreamUpdateStatus() broken 2 ...\n");
@ -2404,11 +2406,11 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
}
else
{
pending_mask.SetBits(blockId, pending_mask.Size());
stream_next_id = blockId + NormBlockId(pending_mask.Size());
pending_mask.SetBits(blockId, pending_mask.GetSize());
stream_next_id = blockId + NormBlockId(pending_mask.GetSize());
// Handle potential sync block id wrap
delta = stream_next_id - stream_sync_id;
if (delta > NormBlockId(2*pending_mask.Size()))
if (delta > NormBlockId(2*pending_mask.GetSize()))
stream_sync_id = blockId;
return true;
}
@ -2420,10 +2422,10 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
{
// For now, let stream begin anytime
pending_mask.Clear();
pending_mask.SetBits(blockId, pending_mask.Size());
pending_mask.SetBits(blockId, pending_mask.GetSize());
stream_sync = true;
stream_sync_id = blockId;
stream_next_id = blockId + pending_mask.Size();
stream_next_id = blockId + pending_mask.GetSize();
read_init = true;
return true;
}
@ -2868,7 +2870,7 @@ UINT32 NormStreamObject::Write(const char* buffer, UINT32 len, bool eom)
{
write_vacancy = false;
DMSG(8, "NormStreamObject::Write() stream buffer full (1)\n", len, eom);
break; // (TBD) skip break if push_mode is enabled???
if (!push_mode) break;
}
NormBlock* block = stream_buffer.Find(write_index.block);
if (!block)
@ -3023,8 +3025,8 @@ UINT32 NormStreamObject::Write(const char* buffer, UINT32 len, bool eom)
if (0 != nBytes)
session.TouchServer();
}
if ((0 != nBytes) && posted_tx_queue_vacancy)
posted_tx_queue_vacancy = false;
//if ((0 != nBytes) && posted_tx_queue_vacancy)
// posted_tx_queue_vacancy = false;
return nBytes;
} // end NormStreamObject::Write()
@ -3114,7 +3116,7 @@ bool NormObjectTable::Init(UINT16 rangeMax, UINT16 tableSize)
if (0 != (tableSize & 0x07)) tableSize = (tableSize >> 3) + 1;
if (!(table = new NormObject*[tableSize]))
{
DMSG(0, "NormObjectTable::Init() table allocation error: %s\n", strerror(errno));
DMSG(0, "NormObjectTable::Init() table allocation error: %s\n", GetErrorString());
return false;
}
memset(table, 0, tableSize*sizeof(char*));

View File

@ -246,9 +246,9 @@ class NormObject
UINT16 nparity;
NormBlockBuffer block_buffer;
bool pending_info; // set when we need to send or recv info
NormSlidingMask pending_mask;
ProtoSlidingMask pending_mask;
bool repair_info; // client: set when
NormSlidingMask repair_mask;
ProtoSlidingMask repair_mask;
NormBlockId current_block_id; // for suppression
NormSegmentId next_segment_id; // for suppression
NormBlockId max_pending_block; // for NACK construction
@ -386,6 +386,7 @@ class NormStreamObject : public NormObject
};
void SetFlushMode(FlushMode flushMode) {flush_mode = flushMode;}
FlushMode GetFlushMode() {return flush_mode;}
void Flush(bool eom = false)
{
FlushMode oldFlushMode = flush_mode;
@ -449,6 +450,8 @@ class NormStreamObject : public NormObject
void SetBlockPoolThreshold(UINT32 value)
{block_pool_threshold = value;}
void ResetPostedTxQueueVacancy() {posted_tx_queue_vacancy = false;}
private:

View File

@ -3,7 +3,6 @@
#include <ctype.h>
#include <string.h>
#include <errno.h>
NormPostProcessor::NormPostProcessor()
: process_argv(NULL), process_argc(0)
@ -89,7 +88,7 @@ bool NormPostProcessor::SetCommand(const char* cmd)
if (!(process_argv = new char*[argCount+2]))
{
DMSG(0, "NormPostProcessor::SetCommand new(process_argv) error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
memset((void*)process_argv, 0, (argCount+2)*sizeof(char**));
@ -109,7 +108,7 @@ bool NormPostProcessor::SetCommand(const char* cmd)
{
SetCommand(NULL);
DMSG(0, "NormPostProcessor::SetCommand new(process_arg) error: %s\n",
strerror(errno));
GetErrorString());
return false;
}
strncpy(arg, argStart, argLength);

View File

@ -1,7 +1,5 @@
#include "normSegment.h"
#include <errno.h> // for strerror()
NormSegmentPool::NormSegmentPool()
: seg_size(0), seg_count(0), seg_total(0), seg_list(NULL),
peak_usage(0), overruns(0), overrun_flag(false)
@ -40,7 +38,7 @@ bool NormSegmentPool::Init(unsigned int count, unsigned int size)
else
{
DMSG(0, "NormSegmentPool::Init() memory allocation error: %s\n",
strerror(errno));
GetErrorString());
seg_total = seg_count;
Destroy();
return false;
@ -111,19 +109,19 @@ bool NormBlock::Init(UINT16 totalSize)
if (segment_table) Destroy();
if (!(segment_table = new char*[totalSize]))
{
DMSG(0, "NormBlock::Init() segment_table allocation error: %s\n", strerror(errno));
DMSG(0, "NormBlock::Init() segment_table allocation error: %s\n", GetErrorString());
return false;
}
memset(segment_table, 0, totalSize*sizeof(char*));
if (!pending_mask.Init(totalSize))
{
DMSG(0, "NormBlock::Init() pending_mask allocation error: %s\n", strerror(errno));
DMSG(0, "NormBlock::Init() pending_mask allocation error: %s\n", GetErrorString());
Destroy();
return false;
}
if (!repair_mask.Init(totalSize))
{
DMSG(0, "NormBlock::Init() repair_mask allocation error: %s\n", strerror(errno));
DMSG(0, "NormBlock::Init() repair_mask allocation error: %s\n", GetErrorString());
Destroy();
return false;
}
@ -652,7 +650,7 @@ bool NormBlockBuffer::Init(unsigned long rangeMax, unsigned long tableSize)
if (0 != (tableSize & 0x07)) tableSize = (tableSize >> 3) + 1;
if (!(table = new NormBlock*[tableSize]))
{
DMSG(0, "NormBlockBuffer::Init() buffer allocation error: %s\n", strerror(errno));
DMSG(0, "NormBlockBuffer::Init() buffer allocation error: %s\n", GetErrorString());
return false;
}
memset(table, 0, tableSize*sizeof(char*));

View File

@ -2,7 +2,7 @@
#define _NORM_SEGMENT
#include "normMessage.h"
#include "normBitmask.h"
#include "protoBitmask.h"
// Norm uses preallocated (or dynamically allocated) pools of
// segments (vectors) for different buffering purposes
@ -240,8 +240,8 @@ class NormBlock
UINT16 parity_count;
UINT16 parity_offset;
NormBitmask pending_mask;
NormBitmask repair_mask;
ProtoBitmask pending_mask;
ProtoBitmask repair_mask;
NormBlock* next;
}; // end class NormBlock

View File

@ -1,5 +1,4 @@
#include "normSession.h"
#include <errno.h>
#include <time.h> // for gmtime() in NormTrace()
@ -16,9 +15,9 @@ const UINT16 NormSession::DEFAULT_NDATA = 64;
const UINT16 NormSession::DEFAULT_NPARITY = 32;
NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
: session_mgr(sessionMgr), notify_pending(false),
tx_socket(ProtoSocket::UDP), rx_socket(ProtoSocket::UDP),
local_node_id(localNodeId),
: session_mgr(sessionMgr), notify_pending(false), tx_port(0),
tx_socket(&tx_socket_actual), tx_socket_actual(ProtoSocket::UDP),
rx_socket(ProtoSocket::UDP), local_node_id(localNodeId),
ttl(DEFAULT_TTL), loopback(false),
tx_rate(DEFAULT_TRANSMIT_RATE/8.0), tx_rate_min(-1.0), tx_rate_max(-1.0),
backoff_factor(DEFAULT_BACKOFF_FACTOR), is_server(false), session_id(0),
@ -41,11 +40,11 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
default_repair_boundary(NormServerNode::BLOCK_BOUNDARY),
default_nacking_mode(NormObject::NACK_NORMAL),
trace(false), tx_loss_rate(0.0), rx_loss_rate(0.0),
next(NULL)
user_data(NULL), next(NULL)
{
interface_name[0] = '\0';
tx_socket.SetNotifier(&sessionMgr.GetSocketNotifier());
tx_socket.SetListener(this, &NormSession::TxSocketRecvHandler);
tx_socket->SetNotifier(&sessionMgr.GetSocketNotifier());
tx_socket->SetListener(this, &NormSession::TxSocketRecvHandler);
rx_socket.SetNotifier(&sessionMgr.GetSocketNotifier());
rx_socket.SetListener(this, &NormSession::RxSocketRecvHandler);
@ -91,15 +90,21 @@ NormSession::~NormSession()
bool NormSession::Open(const char* interfaceName)
{
ASSERT(address.IsValid());
// (TBD) support single socket option
if (!tx_socket.IsOpen())
if (!tx_socket->IsOpen())
{
if (!tx_socket.Open())
if (address.GetPort() != tx_port)
{
if (!tx_socket->Open(tx_port))
{
DMSG(0, "NormSession::Open() tx_socket open error\n");
return false;
}
}
else
{
tx_socket = &rx_socket;
}
}
if (!rx_socket.IsOpen())
{
if (!rx_socket.Open(address.GetPort()))
@ -112,13 +117,13 @@ bool NormSession::Open(const char* interfaceName)
if (address.IsMulticast())
{
if (!tx_socket.SetTTL(ttl))
if (!tx_socket->SetTTL(ttl))
{
DMSG(0, "NormSession::Open() tx_socket set ttl error\n");
Close();
return false;
}
if (!tx_socket.SetLoopback(loopback))
if (!tx_socket->SetLoopback(loopback))
{
DMSG(0, "NormSession::Open() tx_socket set loopback error\n");
Close();
@ -132,7 +137,7 @@ bool NormSession::Open(const char* interfaceName)
if ('\0' != interface_name[0])
{
bool result = rx_socket.SetMulticastInterface(interface_name);
result &= tx_socket.SetMulticastInterface(interface_name);
result &= tx_socket->SetMulticastInterface(interface_name);
if (!result)
{
DMSG(0, "NormSession::Open() error setting multicast interface\n");
@ -157,7 +162,7 @@ bool NormSession::Open(const char* interfaceName)
}
else
{
DMSG(0, "NormSession::Open() new message error: %s\n", strerror(errno));
DMSG(0, "NormSession::Open() new message error: %s\n", GetErrorString());
Close();
return false;
}
@ -175,7 +180,7 @@ void NormSession::Close()
if (tx_timer.IsActive()) tx_timer.Deactivate();
message_queue.Destroy();
message_pool.Destroy();
if (tx_socket.IsOpen()) tx_socket.Close();
if (tx_socket->IsOpen()) tx_socket->Close();
if (rx_socket.IsOpen())
{
if (address.IsMulticast())
@ -196,8 +201,8 @@ bool NormSession::SetMulticastInterface(const char* interfaceName)
bool result = true;
if (rx_socket.IsOpen())
result &= rx_socket.SetMulticastInterface(interfaceName);
if (tx_socket.IsOpen())
result &= tx_socket.SetMulticastInterface(interfaceName);
if (tx_socket->IsOpen())
result &= tx_socket->SetMulticastInterface(interfaceName);
return result;
}
else
@ -837,7 +842,7 @@ NormFileObject* NormSession::QueueTxFile(const char* path,
if (!file)
{
DMSG(0, "NormSession::QueueTxFile() new file object error: %s\n",
strerror(errno));
GetErrorString());
return NULL;
}
if (!file->Open(path, infoPtr, infoLen))
@ -872,7 +877,7 @@ NormDataObject* NormSession::QueueTxData(const char* dataPtr,
if (!obj)
{
DMSG(0, "NormSession::QueueTxData() new data object error: %s\n",
strerror(errno));
GetErrorString());
return NULL;
}
if (!obj->Open((char*)dataPtr, dataLen, false, infoPtr, infoLen))
@ -908,7 +913,7 @@ NormStreamObject* NormSession::QueueTxStream(UINT32 bufferSize,
if (!stream)
{
DMSG(0, "NormSession::QueueTxStream() new stream object error: %s\n",
strerror(errno));
GetErrorString());
return NULL;
}
if (!stream->Open(bufferSize, doubleBuffer, infoPtr, infoLen))
@ -943,7 +948,7 @@ NormSimObject* NormSession::QueueTxSim(unsigned long objectSize)
if (!simObject)
{
DMSG(0, "NormSession::QueueTxSim() new sim object error: %s\n",
strerror(errno));
GetErrorString());
return NULL;
}
@ -1095,7 +1100,7 @@ void NormSession::TxSocketRecvHandler(ProtoSocket& /*theSocket*/,
{
NormMsg msg;
unsigned int msgLength = NormMsg::MAX_SIZE;
while (tx_socket.RecvFrom(msg.AccessBuffer(),
while (tx_socket->RecvFrom(msg.AccessBuffer(),
msgLength,
msg.AccessAddress()))
{
@ -1164,7 +1169,18 @@ void NormTrace(const struct timeval& currentTime,
const ProtoAddress& addr = sent ? msg.GetDestination() : msg.GetSource();
UINT16 seq = msg.GetSequence();
#ifdef _WIN32_WCE
struct tm timeStruct;
timeStruct.tm_hour = currentTime.tv_sec / 3600;
unsigned long hourSecs = 3600 * timeStruct.tm_hour;
timeStruct.tm_min = (currentTime.tv_sec - (hourSecs)) / 60;
timeStruct.tm_sec = currentTime.tv_sec - (hourSecs) - (60*timeStruct.tm_min);
timeStruct.tm_hour = timeStruct.tm_hour % 24;
struct tm* ct = &timeStruct;
#else
struct tm* ct = gmtime((time_t*)&currentTime.tv_sec);
#endif // if/else _WIN32_WCE
DMSG(0, "trace>%02d:%02d:%02d.%06lu node>%lu %s>%s seq>%hu ",
ct->tm_hour, ct->tm_min, ct->tm_sec, currentTime.tv_usec,
(UINT32)localId, status, addr.GetHostString(), seq);
@ -1188,7 +1204,6 @@ void NormTrace(const struct timeval& currentTime,
(UINT16)data.GetObjectId(),
(UINT32)data.GetFecBlockId(),
(UINT16)data.GetFecSymbolId());
if (data.IsData())
{
UINT16 x;
@ -1375,7 +1390,7 @@ void NormSession::ClientHandleObjectMessage(const struct timeval& currentTime,
else
{
DMSG(0, "NormSession::ClientHandleObjectMessage() new NormServerNode error: %s\n",
strerror(errno));
GetErrorString());
// (TBD) notify application of error
return;
}
@ -1432,7 +1447,7 @@ void NormSession::ClientHandleCommand(const struct timeval& currentTime,
else
{
DMSG(0, "NormSession::ClientHandleCommand() new NormServerNode error: %s\n",
strerror(errno));
GetErrorString());
// (TBD) notify application of error
return;
}
@ -1608,7 +1623,7 @@ void NormSession::ServerHandleCCFeedback(NormNodeId nodeId,
else
{
DMSG(0, "NormSession::ServerHandleCCFeedback() memory allocation error: %s\n",
strerror(errno));
GetErrorString());
return;
}
}
@ -1635,7 +1650,7 @@ void NormSession::ServerHandleCCFeedback(NormNodeId nodeId,
else
{
DMSG(0, "NormSession::ServerHandleCCFeedback() memory allocation error: %s\n",
strerror(errno));
GetErrorString());
}
}
else
@ -2667,13 +2682,16 @@ bool NormSession::SendMessage(NormMsg& msg)
}
else
{
if (tx_socket.SendTo(msg.GetBuffer(), msgSize,
if (tx_socket->SendTo(msg.GetBuffer(), msgSize,
msg.GetDestination()))
{
// Separate send/recv tracing
if (trace) NormTrace(currentTime, LocalNodeId(), msg, true);
// Keep track of _actual_ sent rate (TBD) we can do away with this now
// Keep track of _actual_ sent rate
// (TBD) move "sent_rate" tracking to ""OnReportTimeout()
// since it is no longer critical to protocol operation
// but just kept for information purposes ...
if (prev_update_time.tv_sec || prev_update_time.tv_usec)
{
double interval = (double)(currentTime.tv_sec - prev_update_time.tv_sec);
@ -2681,9 +2699,7 @@ bool NormSession::SendMessage(NormMsg& msg)
interval += 1.0e-06*(double)(currentTime.tv_usec - prev_update_time.tv_usec);
else
interval -= 1.0e-06*(double)(prev_update_time.tv_usec - currentTime.tv_usec);
/*sent_rate += 0.125 * (((double)msgSize)/interval - sent_rate);
prev_update_time = currentTime; */
if (interval < grtt_advertised)
if (interval < 1.0) //grtt_advertised)
{
sent_accumulator += msgSize;
}
@ -2955,7 +2971,17 @@ bool NormSession::OnReportTimeout(ProtoTimer& /*theTimer*/)
// Client reporting (just print out for now)
struct timeval currentTime;
ProtoSystemTime(currentTime);
#ifdef _WIN32_WCE
struct tm timeStruct;
timeStruct.tm_hour = currentTime.tv_sec / 3600;
unsigned long hourSecs = 3600 * timeStruct.tm_hour;
timeStruct.tm_min = (currentTime.tv_sec - (hourSecs)) / 60;
timeStruct.tm_sec = currentTime.tv_sec - (hourSecs) - (60*timeStruct.tm_min);
timeStruct.tm_hour = timeStruct.tm_hour % 24;
struct tm* ct = &timeStruct;
#else
struct tm* ct = gmtime((time_t*)&currentTime.tv_sec);
#endif // if/else _WIN32_WCE
DMSG(2, "REPORT time>%02d:%02d:%02d.%06lu node>%lu ***************************************\n",
ct->tm_hour, ct->tm_min, ct->tm_sec, currentTime.tv_usec, LocalNodeId());
if (IsServer())
@ -3047,7 +3073,7 @@ NormSession* NormSessionMgr::NewSession(const char* sessionAddress,
if (!theSession)
{
DMSG(0, "NormSessionMgr::NewSession() new session error: %s\n",
strerror(errno));
GetErrorString());
return ((NormSession*)NULL);
}
theSession->SetAddress(theAddress);

View File

@ -100,26 +100,29 @@ class NormSession
const NormNodeId& LocalNodeId() const {return local_node_id;}
bool Open(const char* interfaceName = NULL);
void Close();
bool IsOpen() {return (rx_socket.IsOpen() || tx_socket.IsOpen());}
bool IsOpen() {return (rx_socket.IsOpen() || tx_socket->IsOpen());}
const ProtoAddress& Address() {return address;}
void SetAddress(const ProtoAddress& addr) {address = addr;}
bool SetMulticastInterface(const char* interfaceName);
bool SetTTL(UINT8 theTTL)
{
bool result = tx_socket.IsOpen() ? tx_socket.SetTTL(theTTL) : true;
bool result = tx_socket->IsOpen() ? tx_socket->SetTTL(theTTL) : true;
ttl = result ? theTTL : ttl;
return result;
}
bool SetLoopback(bool state)
{
bool result = tx_socket.IsOpen() ? tx_socket.SetLoopback(state) : true;
bool result = tx_socket->IsOpen() ? tx_socket->SetLoopback(state) : true;
loopback = result ? state : loopback;
return result;
}
void SetTxPort(UINT16 txPort) {tx_port = txPort;}
static double CalculateRate(double size, double rtt, double loss);
NormSessionMgr& GetSessionMgr() {return session_mgr;}
bool SetTxSocketBuffer(unsigned int bufferSize)
{return tx_socket->SetTxBufferSize(bufferSize);}
bool SetRxSocketBuffer(unsigned int bufferSize)
{return rx_socket.SetRxBufferSize(bufferSize);}
@ -148,6 +151,9 @@ class NormSession
bool SendMessage(NormMsg& msg);
void ActivateTimer(ProtoTimer& timer) {session_mgr.ActivateTimer(timer);}
void SetUserData(const void* userData) {user_data = userData;}
const void* GetUserData() {return user_data;}
// Server methods
void ServerSetBaseObjectId(NormObjectId baseId)
{
@ -209,9 +215,12 @@ class NormSession
double ServerGrtt() {return grtt_advertised;}
void ServerSetGrtt(double grttValue)
{
if (IsServer())
{
double grttMin = 2.0 * ((double)(44+segment_size))/tx_rate;
grttValue = (grttValue < grttMin) ? grttMin : grttValue;
}
grtt_quantized = NormQuantizeRtt(grttValue);
grtt_measured = grtt_advertised = NormUnquantizeRtt(grtt_quantized);
}
@ -332,7 +341,9 @@ class NormSession
NormSessionMgr& session_mgr;
bool notify_pending;
ProtoTimer tx_timer;
ProtoSocket tx_socket;
UINT16 tx_port;
ProtoSocket* tx_socket;
ProtoSocket tx_socket_actual;
ProtoSocket rx_socket;
NormMessageQueue message_queue;
NormMessageQueue message_pool;
@ -360,8 +371,8 @@ class NormSession
UINT16 extra_parity;
NormObjectTable tx_table;
NormSlidingMask tx_pending_mask;
NormSlidingMask tx_repair_mask;
ProtoSlidingMask tx_pending_mask;
ProtoSlidingMask tx_repair_mask;
ProtoTimer repair_timer;
NormBlockPool block_pool;
NormSegmentPool segment_pool;
@ -435,6 +446,8 @@ class NormSession
double tx_loss_rate; // for correlated loss
double rx_loss_rate; // for uncorrelated loss
const void* user_data;
// Linkers
NormSession* next;
}; // end class NormSession

View File

@ -32,29 +32,43 @@ int main(int argc, char* argv[])
"224.1.2.3",
6003,
NORM_NODE_ANY);
// Uncomment to turn on debug NORM message tracing
//NormSetMessageTrace(session, true);
//NormSetTxLoss(session, 1.0); // 10% packet loss
NormSetGrttEstimate(session, 0.001); // 1 msec initial grtt
NormSetTransmitRate(session, 90.0e+06); // in bits/second
NormSetTransmitRate(session, 80.0e+06); // in bits/second
NormSetDefaultRepairBoundary(session, NORM_BOUNDARY_BLOCK);
// Uncomment to use a _specific_ transmit port number
// (Can be the same as session port (rx port), but this
// is _not_ recommended when unicast feedback may be
// possible!
//NormSetTxPort(session, 6001);
// Uncomment to receive your own traffic
//NormSetLoopback(session, true);
NormSetLoopback(session, true);
// Uncomment this line to participate as a receiver
//NormStartReceiver(session, 1024*1024);
// Uncomment to set large rx socket buffer size
// (might be needed for high rate sessions)
// NormSetRxSocketBuffer(session, 512000);
// Uncomment to enable TCP-friendly congestion control
//NormSetCongestionControl(session, true);
// Uncomment the following line to start sender
NormStartSender(session, 4096*1024, 1400, 64, 0);
// Uncomment to set large tx socket buffer size
// (might be needed for high rate sessions)
NormSetTxSocketBuffer(session, 512000);
NormAddAckingNode(session, NormGetLocalNodeId(session));
NormObjectHandle stream = NORM_OBJECT_INVALID;
@ -69,7 +83,6 @@ int main(int argc, char* argv[])
// the stream.
NormStreamSetAutoFlush(stream, NORM_FLUSH_PASSIVE);
// Some variable for stream input/output
char txBuffer[8192], rxBuffer[8192];
int txIndex = 0;
@ -88,10 +101,10 @@ int main(int argc, char* argv[])
{
switch (theEvent.type)
{
case NORM_TX_QUEUE_VACANCY:
// TRACE("NORM_TX_QUEUE_VACANCY ...\n");
case NORM_TX_QUEUE_EMPTY:
//TRACE("NORM_TX_QUEUE_EMPTY ...\n");
case NORM_TX_QUEUE_VACANCY:
//TRACE("NORM_TX_QUEUE_VACANCY ...\n");
if (NORM_OBJECT_INVALID != stream)
{
@ -115,7 +128,7 @@ int main(int argc, char* argv[])
// Instead of "NormStreamSetFlushMode(stream, NORM_FLUSH_PASSIVE)" above
// and "NormStreamMarkEom()" here, I could have used
// "NormStreamFlush(stream, true)" here to perform explicit flushing
// and EOM marking in one fell swoop. That would be a better approach
// and EOM marking in one fell swoop. That would be a simpler approach
// for apps where big stream messages need to be written with
// multiple calls to "NormStreamWrite()"
NormStreamMarkEom(stream);

View File

@ -32,6 +32,6 @@
#ifndef _NORM_VERSION
#define _NORM_VERSION
#define VERSION "1.2b9"
#define VERSION "1.3b1"
#endif // _NORM_VERSION

View File

@ -35,7 +35,7 @@ $(PROTOLIB)/unix/libProtokit.a:
NORM_SRC = $(COMMON)/normMessage.cpp $(COMMON)/normSession.cpp \
$(COMMON)/normNode.cpp $(COMMON)/normObject.cpp \
$(COMMON)/normSegment.cpp $(COMMON)/normBitmask.cpp \
$(COMMON)/normSegment.cpp \
$(COMMON)/normEncoder.cpp $(COMMON)/galois.cpp \
$(COMMON)/normFile.cpp $(COMMON)/normApi.cpp

Binary file not shown.

View File

@ -104,21 +104,6 @@ SOURCE=..\common\normApi.cpp
# End Source File
# Begin Source File
SOURCE=..\common\normBitmask.cpp
!IF "$(CFG)" == "NormLib - Win32 Release"
# ADD CPP /MD /vmg /I "..\win32"
!ELSEIF "$(CFG)" == "NormLib - Win32 Debug"
# ADD CPP /MDd /vmg /I "..\win32"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\common\normEncoder.cpp
!IF "$(CFG)" == "NormLib - Win32 Release"

View File

@ -3,7 +3,9 @@
#include "normPostProcess.h"
#include "protoDebug.h"
#ifndef _WIN32_WCE
#include <ddeml.h>
#endif // !_WIN32_WCE
#include <shellapi.h>
#include <stdio.h>
@ -17,23 +19,26 @@ class Win32PostProcessor : public NormPostProcessor
bool IsActive() {return (NULL != post_processor_handle);}
private:
static HDDEDATA CALLBACK DDEClientCallback(UINT uiType, UINT uiFmt, HCONV hConv,
HSZ sz1, HSZ sz2, HDDEDATA hData,
DWORD lData1, DWORD lData2);
friend class NormPostProcessor;
Win32PostProcessor();
bool Init();
#ifndef _WIN32_WCE
static HDDEDATA CALLBACK DDEClientCallback(UINT uiType, UINT uiFmt, HCONV hConv,
HSZ sz1, HSZ sz2, HDDEDATA hData,
DWORD lData1, DWORD lData2);
// Post Processor DDE state
DWORD lIdInst; // DDE instance id
HCONV hConv; // dde converstation handle
DWORD transaction_id;
DWORD window_id; // dde browser window id
PFNCALLBACK lpDDECallback;
#endif // !_WIN32_WCE
HANDLE post_processor_handle;
}; // end class Win32PostProcessor
#ifndef _WIN32_WCE
HDDEDATA CALLBACK Win32PostProcessor::DDEClientCallback(UINT uiType, UINT uiFmt, HCONV hConv,
HSZ sz1, HSZ sz2, HDDEDATA hData,
DWORD lData1, DWORD lData2)
@ -95,9 +100,14 @@ HDDEDATA CALLBACK Win32PostProcessor::DDEClientCallback(UINT uiType, UINT uiFmt,
}
return NULL; // callback does nothing for now
}
#endif // !_WIN32_WCE
Win32PostProcessor::Win32PostProcessor()
: lIdInst(0), hConv(NULL), window_id(-1),
:
#ifndef _WIN32_WCE
lIdInst(0), hConv(NULL), window_id(-1),
#endif // !_WIN32_WCE
post_processor_handle(NULL)
{
@ -106,11 +116,13 @@ Win32PostProcessor::Win32PostProcessor()
Win32PostProcessor::~Win32PostProcessor()
{
Kill();
#ifndef _WIN32_WCE
if (lIdInst)
{
::DdeUninitialize(lIdInst);
lIdInst = 0;
}
#endif // !_WIN32_WCE
}
NormPostProcessor* NormPostProcessor::Create()
@ -128,7 +140,8 @@ NormPostProcessor* NormPostProcessor::Create()
bool Win32PostProcessor::Init()
{
// Init DDE
#ifndef _WIN32_WCE
// Init DDE
if (0 != lIdInst)
{
// already exists
@ -142,21 +155,21 @@ bool Win32PostProcessor::Init()
{
return false;
}
else
{
}
#endif // !_WIN32_WCE
return true;
}
}
} // end Win32PostProcessor::Init()
void Win32PostProcessor::Kill()
{
#ifndef _WIN32_WCE
if (hConv)
{
DdeDisconnect(hConv);
hConv = NULL;
}
#endif // !_WIN32_WCE
if (post_processor_handle)
{
TerminateProcess(post_processor_handle, 0);
@ -168,7 +181,7 @@ void Win32PostProcessor::Kill()
bool Win32PostProcessor::ProcessFile(const char *path)
{
#ifndef _WIN32_WCE
// DDE seems to be broken for the moment
// (It does work if the serving applications is _already_ running
// so these two lines of code disable it for the moment)
@ -217,6 +230,7 @@ bool Win32PostProcessor::ProcessFile(const char *path)
// For now we assume the DDE server name & command name are the
// same and that the post processor command executable is in
// the PATH
#endif // !_WIN32_WCE
// Kill old PostProcessor first
Kill();
@ -230,6 +244,19 @@ bool Win32PostProcessor::ProcessFile(const char *path)
}
strcat(args, path);
#ifdef _UNICODE
wchar_t cmdBuffer[PATH_MAX];
mbstowcs(cmdBuffer, process_argv[0], PATH_MAX);
wchar_t* cmdPtr = cmdBuffer;
wchar_t argsBuffer[PATH_MAX+512];
mbstowcs(argsBuffer, args, PATH_MAX+512);
wchar_t* argPtr = argsBuffer;
#else
char* cmdPtr = process_argv[0];
char* argPtr = args;
#endif // if/else _UNICODE
DMSG(4, "Win32PostProcessor::ProcessFile() execing \"%s %s\"\n", process_argv[0], args);
SHELLEXECUTEINFO exeInfo;
@ -237,8 +264,8 @@ bool Win32PostProcessor::ProcessFile(const char *path)
exeInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
exeInfo.hwnd = NULL;
exeInfo.lpVerb = NULL;
exeInfo.lpFile = process_argv[0];
exeInfo.lpParameters = args;
exeInfo.lpFile = cmdPtr;
exeInfo.lpParameters = argPtr;
exeInfo.lpDirectory = NULL;
exeInfo.nShow = SW_SHOW;
if (!ShellExecuteEx(&exeInfo))

BIN
wince/Norm.vco Normal file

Binary file not shown.

1373
wince/Norm.vcp Normal file

File diff suppressed because it is too large Load Diff

59
wince/Norm.vcw Normal file
View File

@ -0,0 +1,59 @@
Microsoft eMbedded Visual Tools Workspace File, Format Version 4.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "Norm"=.\Norm.vcp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "Protokit"=..\protolib\wince\Protokit.vcp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "normApp"=.\normApp\normApp.vcp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name Norm
End Project Dependency
Begin Project Dependency
Project_Dep_Name Protokit
End Project Dependency
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

377
wince/normApp/normApp.vcp Normal file
View File

@ -0,0 +1,377 @@
# Microsoft eMbedded Visual Tools Project File - Name="normApp" - Package Owner=<4>
# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02
# ** DO NOT EDIT **
# TARGTYPE "Win32 (WCE ARMV4) Application" 0xa301
# TARGTYPE "Win32 (WCE emulator) Application" 0xa601
CFG=normApp - Win32 (WCE emulator) Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "normApp.vcn".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "normApp.vcn" CFG="normApp - Win32 (WCE emulator) Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "normApp - Win32 (WCE emulator) Release" (based on "Win32 (WCE emulator) Application")
!MESSAGE "normApp - Win32 (WCE emulator) Debug" (based on "Win32 (WCE emulator) Application")
!MESSAGE "normApp - Win32 (WCE ARMV4) Release" (based on "Win32 (WCE ARMV4) Application")
!MESSAGE "normApp - Win32 (WCE ARMV4) Debug" (based on "Win32 (WCE ARMV4) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
# PROP ATL_Project 2
!IF "$(CFG)" == "normApp - Win32 (WCE emulator) Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "emulatorRel"
# PROP BASE Intermediate_Dir "emulatorRel"
# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "emulatorRel"
# PROP Intermediate_Dir "emulatorRel"
# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /r
# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /r
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "_i386_" /D UNDER_CE=$(CEVersion) /D "i_386_" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "NDEBUG" /YX /Gs8192 /GF /O2 /c
# ADD CPP /nologo /W3 /I "..\common" /I "..\protolib\common" /I "..\protolib\win32" /D "_i386_" /D "i_386_" /D "_X86_" /D "x86" /D "NDEBUG" /D "WIN32" /D "PROTO_DEBUG" /D "HAVE_ASSERT" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /U "UNIX" /U "HAVE_IPV6" /U "SIMULATE" /U "NS2" /U "OPNET" /YX /Gs8192 /GF /O2 /c
MTL=midl.exe
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 commctrl.lib coredll.lib $(CEx86Corelibc) aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:$(CENoDefaultLib) /subsystem:$(CESubsystem) /MACHINE:IX86
# ADD LINK32 $(CEx86Corelibc) ws2.lib iphlpapi.lib commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:$(CENoDefaultLib) /subsystem:$(CESubsystem) /MACHINE:IX86
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE emulator) Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "emulatorDbg"
# PROP BASE Intermediate_Dir "emulatorDbg"
# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "emulatorDbg"
# PROP Intermediate_Dir "emulatorDbg"
# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "$(CePlatform)" /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "_X86_" /d "x86" /d "_i386_" /r
# ADD RSC /l 0x409 /d "$(CePlatform)" /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "_X86_" /d "x86" /d "_i386_" /r
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "i_386_" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /YX /Gs8192 /GF /c
# ADD CPP /nologo /W3 /Zi /Od /I "..\common" /I "..\protolib\common" /I "..\protolib\win32" /D "DEBUG" /D "_i386_" /D "i_386_" /D "_X86_" /D "x86" /D "WIN32" /D "PROTO_DEBUG" /D "HAVE_ASSERT" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /U "UNIX" /U "HAVE_IPV6" /U "SIMULATE" /U "NS2" /U "OPNET" /YX /Gs8192 /GF /c
MTL=midl.exe
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 commctrl.lib coredll.lib $(CEx86Corelibc) aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /debug /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:$(CENoDefaultLib) /subsystem:$(CESubsystem) /MACHINE:IX86
# ADD LINK32 $(CEx86Corelibc) ws2.lib iphlpapi.lib commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /debug /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:$(CENoDefaultLib) /subsystem:$(CESubsystem) /MACHINE:IX86
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ARMV4Rel"
# PROP BASE Intermediate_Dir "ARMV4Rel"
# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "ARMV4Rel"
# PROP Intermediate_Dir "ARMV4Rel"
# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r
# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r
CPP=clarm.exe
# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /YX /O2 /M$(CECrtMT) /c
# ADD CPP /nologo /W3 /I "..\..\common" /I "..\..\protolib\common" /I "..\..\protolib\win32" /D "ARM" /D "_ARM_" /D "ARMV4" /D "NDEBUG" /D "WIN32" /D "PROTO_DEBUG" /D "HAVE_ASSERT" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /U "UNIX" /U "HAVE_IPV6" /U "SIMULATE" /U "NS2" /U "OPNET" /YX /O2 /M$(CECrtMT) /c
MTL=midl.exe
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
# ADD LINK32 ws2.lib iphlpapi.lib commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ARMV4Dbg"
# PROP BASE Intermediate_Dir "ARMV4Dbg"
# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "ARMV4Dbg"
# PROP Intermediate_Dir "ARMV4Dbg"
# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r
# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r
CPP=clarm.exe
# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /YX /M$(CECrtMTDebug) /c
# ADD CPP /nologo /W3 /Zi /Od /I "..\common" /I "..\protolib\common" /I "..\protolib\win32" /D "DEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D "WIN32" /D "PROTO_DEBUG" /D "HAVE_ASSERT" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /U "UNIX" /U "HAVE_IPV6" /U "SIMULATE" /U "NS2" /U "OPNET" /YX /M$(CECrtMTDebug) /c
MTL=midl.exe
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
# ADD LINK32 ws2.lib iphlpapi.lib commctrl.lib coredll.lib aygshell.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"WinMainCRTStartup" /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
!ENDIF
# Begin Target
# Name "normApp - Win32 (WCE emulator) Release"
# Name "normApp - Win32 (WCE emulator) Debug"
# Name "normApp - Win32 (WCE ARMV4) Release"
# Name "normApp - Win32 (WCE ARMV4) Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\common\normApp.cpp
!IF "$(CFG)" == "normApp - Win32 (WCE emulator) Release"
DEP_CPP_NORMA=\
"..\..\common\normBitmask.h"\
"..\..\common\normEncoder.h"\
"..\..\common\normFile.h"\
"..\..\common\normMessage.h"\
"..\..\common\normNode.h"\
"..\..\common\normObject.h"\
"..\..\common\normPostProcess.h"\
"..\..\common\normSegment.h"\
"..\..\common\normSession.h"\
NODEP_CPP_NORMA=\
"..\..\common\protoDefs.h"\
"..\..\common\protokit.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE emulator) Debug"
DEP_CPP_NORMA=\
"..\..\common\normBitmask.h"\
"..\..\common\normEncoder.h"\
"..\..\common\normFile.h"\
"..\..\common\normMessage.h"\
"..\..\common\normNode.h"\
"..\..\common\normObject.h"\
"..\..\common\normPostProcess.h"\
"..\..\common\normSegment.h"\
"..\..\common\normSession.h"\
NODEP_CPP_NORMA=\
"..\..\common\protoDefs.h"\
"..\..\common\protokit.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Release"
DEP_CPP_NORMA=\
"..\..\common\normEncoder.h"\
"..\..\common\normFile.h"\
"..\..\common\normMessage.h"\
"..\..\common\normNode.h"\
"..\..\common\normObject.h"\
"..\..\common\normPostProcess.h"\
"..\..\common\normSegment.h"\
"..\..\common\normSession.h"\
"..\..\protolib\common\protoAddress.h"\
"..\..\protolib\common\protoApp.h"\
"..\..\protolib\common\protoBitmask.h"\
"..\..\protolib\common\protoChannel.h"\
"..\..\protolib\common\protoDebug.h"\
"..\..\protolib\common\protoDefs.h"\
"..\..\protolib\common\protoDispatcher.h"\
"..\..\protolib\common\protokit.h"\
"..\..\protolib\common\protoPipe.h"\
"..\..\protolib\common\protoRouteMgr.h"\
"..\..\protolib\common\protoRouteTable.h"\
"..\..\protolib\common\protoSocket.h"\
"..\..\protolib\common\protoTimer.h"\
"..\..\protolib\common\protoTree.h"\
"..\..\protolib\common\protoVersion.h"\
"..\..\protolib\win32\tpipv6.h"\
"..\..\protolib\win32\wspiapi.h"\
{$(INCLUDE)}"basetsd.h"\
{$(INCLUDE)}"guiddef.h"\
NODEP_CPP_NORMA=\
"..\..\protolib\common\config.h"\
"..\..\protolib\common\ip_addr_v4.h"\
"..\..\protolib\common\nsProtoSimAgent.h"\
"..\..\protolib\common\opnet.h"\
"..\..\protolib\common\scheduler.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Debug"
DEP_CPP_NORMA=\
"..\..\common\normBitmask.h"\
"..\..\common\normEncoder.h"\
"..\..\common\normFile.h"\
"..\..\common\normMessage.h"\
"..\..\common\normNode.h"\
"..\..\common\normObject.h"\
"..\..\common\normPostProcess.h"\
"..\..\common\normSegment.h"\
"..\..\common\normSession.h"\
NODEP_CPP_NORMA=\
"..\..\common\protoDefs.h"\
"..\..\common\protokit.h"\
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\common\normPostProcess.cpp
!IF "$(CFG)" == "normApp - Win32 (WCE emulator) Release"
DEP_CPP_NORMP=\
"..\..\common\normPostProcess.h"\
NODEP_CPP_NORMP=\
"..\..\common\protoDebug.h"\
"..\..\common\protoDefs.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE emulator) Debug"
DEP_CPP_NORMP=\
"..\..\common\normPostProcess.h"\
NODEP_CPP_NORMP=\
"..\..\common\protoDebug.h"\
"..\..\common\protoDefs.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Release"
DEP_CPP_NORMP=\
"..\..\common\normPostProcess.h"\
"..\..\protolib\common\protoDebug.h"\
"..\..\protolib\common\protoDefs.h"\
{$(INCLUDE)}"basetsd.h"\
NODEP_CPP_NORMP=\
"..\..\protolib\common\opnet.h"\
"..\..\protolib\common\scheduler.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Debug"
DEP_CPP_NORMP=\
"..\..\common\normPostProcess.h"\
NODEP_CPP_NORMP=\
"..\..\common\protoDebug.h"\
"..\..\common\protoDefs.h"\
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\win32\win32PostProcess.cpp
!IF "$(CFG)" == "normApp - Win32 (WCE emulator) Release"
NODEP_CPP_WIN32=\
"..\..\win32\normPostProcess.h"\
"..\..\win32\protoDebug.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE emulator) Debug"
NODEP_CPP_WIN32=\
"..\..\win32\normPostProcess.h"\
"..\..\win32\protoDebug.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Release"
DEP_CPP_WIN32=\
"..\..\common\normPostProcess.h"\
"..\..\protolib\common\protoDebug.h"\
"..\..\protolib\common\protoDefs.h"\
{$(INCLUDE)}"basetsd.h"\
NODEP_CPP_WIN32=\
"..\..\protolib\common\opnet.h"\
"..\..\protolib\common\scheduler.h"\
!ELSEIF "$(CFG)" == "normApp - Win32 (WCE ARMV4) Debug"
NODEP_CPP_WIN32=\
"..\..\win32\normPostProcess.h"\
"..\..\win32\protoDebug.h"\
!ENDIF
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project