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="GENERATOR" CONTENT="OpenOffice.org 1.1.2 (Linux)">
<META NAME="AUTHOR" CONTENT="Robert Adamson"> <META NAME="AUTHOR" CONTENT="Robert Adamson">
<META NAME="CREATED" CONTENT="20040824;15180000"> <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="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 "> <META NAME="KEYWORDS" CONTENT="norm object value application function ">
<STYLE> <STYLE>
@ -64,7 +64,9 @@ United States Naval Research Laboratory (NRL). The NORM protocol
provides general purpose reliable data transport for applications provides general purpose reliable data transport for applications
wishing to use Internet Protocol (IP) Multicast services for group wishing to use Internet Protocol (IP) Multicast services for group
data delivery. NORM can also support unicast (point-to-point) data 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 <P CLASS="western" STYLE="font-style: normal">The NORM protocol is
designed to provide end-to-end reliable transport of bulk data designed to provide end-to-end reliable transport of bulk data
objects or streams over generic IP multicast routing and forwarding 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. level transport protocols to utilize its service in different ways.
The protocol leverages the use of FEC-based repair and other proven The protocol leverages the use of FEC-based repair and other proven
reliable multicast transport techniques in its design.</P> reliable multicast transport techniques in its design.</P>
<H1 CLASS="western" ALIGN=CENTER STYLE="page-break-before: always">Table <H1 CLASS="western" ALIGN=CENTER STYLE="page-break-before: always">Contents</H1>
of Contents</H1>
<DIV ID="Table of Contents1" DIR="LTR"> <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.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 <P STYLE="margin-top: 0.17in; font-style: normal"><FONT SIZE=2><B>API
Initialization</B></FONT></P> 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="#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-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 <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="#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="#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> <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> 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="#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="#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="#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="#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="#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> <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="#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="#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="#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="#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="#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> <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> 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="#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="#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="#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="#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> <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> the application via the <FONT FACE="Courier"><A HREF="#NormGetNextEvent()">NormGetNextEvent()</A></FONT>
function call. function call.
</P> </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 <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 the NORM API is to create an &quot;instance&quot; of the NORM
protocol engine. Note that multiple instances may be created by the 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 <P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include
&lt;normApi.h&gt;</FONT></FONT></P> &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> <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> <H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function creates <P CLASS="western" STYLE="font-style: normal">This function creates
an instance of a NORM protocol engine and is the necessary first step 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 of the NORM protocol engine, an operating system thread is created
for protocol execution. The returned <FONT FACE="Courier"><A HREF="#NormInstanceHandle">NormInstanceHandle</A> 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>value may be used in subsequent API calls as needed, such
<FONT FACE="Courier">NormCreateSesssion()</FONT>, etc. <FONT FACE="Courier">NormCreateSesssion()</FONT>, etc. The optional
</P> <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> <H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">A value of <P CLASS="western" STYLE="font-style: normal">A value of
<FONT FACE="Courier">NORM_INSTANCE_INVALID</FONT> is returned upon <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 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> are retrieved by the application via the <FONT FACE="Courier"><A HREF="#NormGetNextEvent()">NormGetNextEvent()</A></FONT>
function call.</P> function call.</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0> <TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=123*> <COL WIDTH=269>
<COL WIDTH=133*> <COL WIDTH=293>
<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"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Sender Notification Event Types:</B></P> <B>Sender Notification Event Types:</B></P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_QUEUE_VACANCY</I></FONT></P> <FONT FACE="Courier"><I>NORM_TX_QUEUE_VACANCY</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that there is room for additional transmit 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> 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 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> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_QUEUE_EMPTY</I></FONT></P> <FONT FACE="Courier"><I>NORM_TX_QUEUE_EMPTY</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates the NORM protocol engine has no new data This event indicates the NORM protocol engine has no new data
pending transmission and the application may enqueue additional pending transmission and the application may enqueue additional
@ -622,11 +640,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_OBJECT_SENT</I></FONT></P> <FONT FACE="Courier"><I>NORM_TX_OBJECT_SENT</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the transport object referenced by the This event indicates that the transport object referenced by the
event's &quot;object&quot; field has completed at least one pass event's &quot;object&quot; field has completed at least one pass
@ -638,11 +656,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_TX_OBJECT_PURGED</I></FONT></P> <FONT FACE="Courier"><I>NORM_TX_OBJECT_PURGED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the NORM protocol engine will no longer This event indicates that the NORM protocol engine will no longer
refer to the transport object identified by the event's &quot;object' refer to the transport object identified by the event's &quot;object'
@ -657,11 +675,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_LOCAL_SERVER_CLOSED</I></FONT></P> <FONT FACE="Courier"><I>NORM_LOCAL_SERVER_CLOSED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when the NORM protocol engine completes the This event is posted when the NORM protocol engine completes the
&quot;graceful shutdown&quot; of its participation as a sender in &quot;graceful shutdown&quot; of its participation as a sender in
@ -669,17 +687,17 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<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"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Receiver Notification Event Types:</B></P> <B>Receiver Notification Event Types:</B></P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_NEW</I></FONT></P> <FONT FACE="Courier"><I>NORM_REMOTE_SERVER_NEW</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when a receiver first receives This notification is posted when a receiver first receives
messages from a specific remote NORM server. This marks the messages from a specific remote NORM server. This marks the
@ -688,11 +706,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_ACTIVE</I></FONT></P> <FONT FACE="Courier"><I>NORM_REMOTE_SERVER_ACTIVE</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when a previously inactive (or new) remote This event is posted when a previously inactive (or new) remote
server is detected operating as an active sender within the server is detected operating as an active sender within the
@ -700,11 +718,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_INACTIVE</I></FONT></P> <FONT FACE="Courier"><I>NORM_REMOTE_SERVER_INACTIVE</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted after a significant period of inactivity (no This event is posted after a significant period of inactivity (no
sender messages received) of a specific NORM sender within the sender messages received) of a specific NORM sender within the
@ -713,22 +731,22 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_REMOTE_SERVER_PURGED</I></FONT></P> <FONT FACE="Courier"><I>NORM_REMOTE_SERVER_PURGED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when the NORM protocol engine frees resources This event is posted when the NORM protocol engine frees resources
for, and thus invalidates the indicated &quot;node&quot; handle.</P> for, and thus invalidates the indicated &quot;node&quot; handle.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_NEW</I></FONT></P> <FONT FACE="Courier"><I>NORM_RX_OBJECT_NEW</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when reception of a new transport object This event is posted when reception of a new transport object
begins and marks the beginning of the interval during which the begins and marks the beginning of the interval during which the
@ -737,33 +755,33 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_INFO</I></FONT></P> <FONT FACE="Courier"><I>NORM_RX_OBJECT_INFO</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when the NORM_INFO content for the This notification is posted when the NORM_INFO content for the
indicated &quot;object&quot; is received.</P> indicated &quot;object&quot; is received.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_UPDATED</I></FONT></P> <FONT FACE="Courier"><I>NORM_RX_OBJECT_UPDATED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event indicates that the identified receive &quot;object&quot; This event indicates that the identified receive &quot;object&quot;
has newly received data content.</P> has newly received data content.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_COMPLETED</I></FONT></P> <FONT FACE="Courier"><I>NORM_RX_OBJECT_COMPLETED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This event is posted when a receive object is completely received, This event is posted when a receive object is completely received,
including available NORM_INFO content. Unless the application including available NORM_INFO content. Unless the application
@ -773,11 +791,11 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_RX_OBJECT_ABORTED</I></FONT></P> <FONT FACE="Courier"><I>NORM_RX_OBJECT_ABORTED</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This notification is posted when a pending receive object's This notification is posted when a pending receive object's
transmission is aborted by the remote sender. Unless the transmission is aborted by the remote sender. Unless the
@ -787,17 +805,17 @@ function call.</P>
</TD> </TD>
</TR> </TR>
<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"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<B>Miscellaneous Notification Event Types</B></P> <B>Miscellaneous Notification Event Types</B></P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=48%> <TD WIDTH=269>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><I>NORM_EVENT_INVALID</I></FONT></P> <FONT FACE="Courier"><I>NORM_EVENT_INVALID</I></FONT></P>
</TD> </TD>
<TD WIDTH=52%> <TD WIDTH=293>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This <A HREF="#NormEventType">NormEventType</A> indicates an invalid or &quot;null&quot; This <A HREF="#NormEventType">NormEventType</A> indicates an invalid or &quot;null&quot;
notification which should be ignored.</P> 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 <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 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 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> events if undesired)).</P>
<H3 CLASS="functionheading-western"><A NAME="NormGetDescriptor()">NormGetDescriptor()</A></H3> <H3 CLASS="functionheading-western"><A NAME="NormGetDescriptor()">NormGetDescriptor()</A></H3>
<H4 CLASS="western">Synopsis</H4> <H4 CLASS="western">Synopsis</H4>
@ -845,8 +863,8 @@ usage, the NORM descriptor should be treated as a &quot;read&quot;
descriptor.</P> descriptor.</P>
<H4 CLASS="western">Return Values</H4> <H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">A descriptor is <P CLASS="western" STYLE="font-style: normal">A descriptor is
returned which is valid until a call to <A HREF="#NormDestroyInstance()">NormDestroyInstance()</A> is returned which is valid until a call to <FONT FACE="Courier"><A HREF="#NormDestroyInstance()">NormDestroyInstance()</A></FONT>
made. Upon error, a value of <I><FONT FACE="Courier">NORM_DESCRIPTOR_INVALID</FONT></I> is made. Upon error, a value of <I><FONT FACE="Courier">NORM_DESCRIPTOR_INVALID</FONT></I>
is returned.</P> is returned.</P>
<H2 CLASS="western">Session Creation and Control</H2> <H2 CLASS="western">Session Creation and Control</H2>
<H3 CLASS="functionheading-western"><A NAME="NormCreateSession()">NormCreateSession()</A></H3> <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 <FONT FACE="Courier"><A HREF="#NormStartReceiver()">NormStartReceiver()</A></FONT> to join the specified
multicast group (if applicable) and start protocol operation. The multicast group (if applicable) and start protocol operation. The
following parameters are required in this function call:</P> following parameters are required in this function call:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0> <TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=50*> <COL WIDTH=101>
<COL WIDTH=206*> <COL WIDTH=461>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=20%> <TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">instance</FONT></P> <FONT FACE="Courier">instance</FONT></P>
</TD> </TD>
<TD WIDTH=80%> <TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <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> 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> previously obtained with a call to <FONT FACE="Courier"><A HREF="#NormCreateInstance()">NormCreateInstance()</A></FONT>.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=20%> <TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">address</FONT></P> <FONT FACE="Courier">address</FONT></P>
</TD> </TD>
<TD WIDTH=80%> <TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This points to a string containing an IP address (e.g. dotted This points to a string containing an IP address (e.g. dotted
decimal IPv4 address (or IPv6 address) or name resolvable to a 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> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=20%> <TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">port</FONT></P> <FONT FACE="Courier">port</FONT></P>
</TD> </TD>
<TD WIDTH=80%> <TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This must be a valid, unused port number corresponding to the This must be a valid, unused port number corresponding to the
desired NORM session address. See the <U><FONT FACE="Courier">address</FONT></U> 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> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=20%> <TD WIDTH=101>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier">localId</FONT></P> <FONT FACE="Courier">localId</FONT></P>
</TD> </TD>
<TD WIDTH=80%> <TD WIDTH=461>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
The <FONT FACE="Courier">localId</FONT> parameter specifies the The <FONT FACE="Courier">localId</FONT> parameter specifies the
<FONT FACE="Courier"><A HREF="#NormNodeId">NormNodeId</A></FONT> that should be used to <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> <H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no <P CLASS="western" STYLE="font-style: normal">This function has no
returned values.</P> 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> <H3 CLASS="functionheading-western"><A NAME="NormGetLocalNodeId()">NormGetLocalNodeId()</A></H3>
<H4 CLASS="western">Synopsis</H4> <H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include <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 indicates the <I>NormNode</I> identifier used by the NORM protocol
engine for the local application's participation in the specified engine for the local application's participation in the specified
<I>NormSession</I>.</P> <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> <H3 CLASS="functionheading-western"><A NAME="NormSetMulticastInterface()">NormSetMulticastInterface()</A></H3>
<H4 CLASS="western">Synopsis</H4> <H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include <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 feedback collection and application API activity such as posting of
sender-related <I>NormEvents</I>. The parameters required for this sender-related <I>NormEvents</I>. The parameters required for this
function call include:</P> function call include:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0> <TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=56*> <COL WIDTH=106>
<COL WIDTH=200*> <COL WIDTH=456>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=22%> <TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>session</U></FONT></P> <FONT FACE="Courier"><U>session</U></FONT></P>
</TD> </TD>
<TD WIDTH=78%> <TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <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> 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> previously obtained with a call to <FONT FACE="Courier"><A HREF="#NormCreateSession()">NormCreateSession()</A></FONT>.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=22%> <TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>bufferSpace</U></FONT></P> <FONT FACE="Courier"><U>bufferSpace</U></FONT></P>
</TD> </TD>
<TD WIDTH=78%> <TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This specifies the maximum memory space the NORM protocol engine This specifies the maximum memory space the NORM protocol engine
is allowed to use to buffer any sender calculated FEC segments and is allowed to use to buffer any sender calculated FEC segments and
@ -1155,11 +1235,11 @@ function call include:</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=22%> <TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>segmentSize</U></FONT></P> <FONT FACE="Courier"><U>segmentSize</U></FONT></P>
</TD> </TD>
<TD WIDTH=78%> <TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the maximum <I>payload</I> size (in bytes) of This parameter sets the maximum <I>payload</I> size (in bytes) of
NORM sender messages (<I>not</I> including any NORM message header NORM sender messages (<I>not</I> including any NORM message header
@ -1181,21 +1261,21 @@ function call include:</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=22%> <TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>blockSize</U></FONT></P> <FONT FACE="Courier"><U>blockSize</U></FONT></P>
</TD> </TD>
<TD WIDTH=78%> <TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the number of source symbol segments (packets) This parameter sets the number of source symbol segments (packets)
per coding block, for the systematic Reed-Solomon FEC code used in per coding block, for the systematic Reed-Solomon FEC code used in
the current NORM implementation. For traditional systematic block the current NORM implementation. For traditional systematic block
code &quot;<I>(n,k)</I>&quot; nomenclature, the <FONT FACE="Courier"><U>blockSize</U></FONT> 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 value corresponds to <I>&quot;k&quot;.</I> NORM logically
transport object data content into coding blocks and the <FONT FACE="Courier"><U>blockSize</U></FONT> segments transport object data content into coding blocks and the
parameter determines the number of source symbol segments <FONT FACE="Courier"><U>blockSize</U></FONT> parameter determines
(packets) comprising a single coding block where each source the number of source symbol segments (packets) comprising a single
symbol segment is up to <FONT FACE="Courier"><U>segmentSize</U></FONT> 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 bytes in length.. A given block's parity symbol segments are
calculated using the corresponding set of source symbol segments. calculated using the corresponding set of source symbol segments.
The maximum <FONT FACE="Courier"><U>blockSize</U></FONT> allowed The maximum <FONT FACE="Courier"><U>blockSize</U></FONT> allowed
@ -1205,11 +1285,11 @@ function call include:</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <TR VALIGN=TOP>
<TD WIDTH=22%> <TD WIDTH=106>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
<FONT FACE="Courier"><U>numParity</U></FONT></P> <FONT FACE="Courier"><U>numParity</U></FONT></P>
</TD> </TD>
<TD WIDTH=78%> <TD WIDTH=456>
<P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid"> <P CLASS="western" STYLE="font-style: normal; page-break-inside: avoid">
This parameter sets the maximum number of parity symbol segments This parameter sets the maximum number of parity symbol segments
(packets) the sender is willing to <I>calculate</I> per FEC coding (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> the corresponding <FONT FACE="Courier"><U>blockSize</U></FONT>
source symbol segments. In the &quot;<I>(n,k)&quot;</I> source symbol segments. In the &quot;<I>(n,k)&quot;</I>
nomenclature mention above, the <FONT FACE="Courier"><U>numParity</U></FONT> 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 Reed-Solomon FEC codes used in the current NORM implementation is
that one parity segment can fill any one erasure (missing segment 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>, (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> <H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no <P CLASS="western" STYLE="font-style: normal">This function has no
return values.</P> 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> <H3 CLASS="functionheading-western"><A NAME="NormSetCongestionControl()">NormSetCongestionControl()</A></H3>
<H4 CLASS="western">Synopsis</H4> <H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include <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> <H4 CLASS="western">Description</H4>
<P CLASS="western" STYLE="font-style: normal">This function sets the <P CLASS="western" STYLE="font-style: normal">This function sets the
sender's estimate of group round-trip timing (GRTT). This function 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> 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 when the application has <I>a priori</I> confidence that the default
initial GRTT value of 0.5 second is inappropriate. The sender GRTT 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 is active. For experimental purposes (or very special application
needs), this API provides a mechanism to control or disable the needs), this API provides a mechanism to control or disable the
sender GRTT update process (see <FONT FACE="Courier">NormSetGrttProbing()</FONT>). sender GRTT update process (see <FONT FACE="Courier">NormSetGrttProbing()</FONT>).
The grtt value will be limited to the maximum GRTT as set (see The <FONT FACE="Courier"><U>grtt</U></FONT> value will be limited to
<FONT FACE="Courier">NormSetGrttMax()) </FONT>or the default maximum the maximum GRTT as set (see <FONT FACE="Courier">NormSetGrttMax())
of 10 seconds. </FONT>or the default maximum of 10 seconds.
</P> </P>
<P CLASS="western" STYLE="font-style: normal">The sender GRTT is <P CLASS="western" STYLE="font-style: normal">The sender GRTT is
advertised to the receiver group and is used to scale various NORM 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> <H4 CLASS="western">Return Values</H4>
<P CLASS="western" STYLE="font-style: normal">This function has no <P CLASS="western" STYLE="font-style: normal">This function has no
return values.</P> 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> <H3 CLASS="functionheading-western"><A NAME="NormSetSilentReceiver()">NormSetSilentReceiver()</A></H3>
<H4 CLASS="western">Synopsis</H4> <H4 CLASS="western">Synopsis</H4>
<P STYLE="font-style: normal; page-break-after: avoid"><FONT FACE="Courier"><FONT SIZE=2>#include <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 request repair of objects in which they are really interested in
receiving, some overall savings in unnecessary network loading might receiving, some overall savings in unnecessary network loading might
be realized. Available nacking modes include:</P> be realized. Available nacking modes include:</P>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=7 CELLSPACING=0 STYLE="page-break-inside: avoid"> <TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
<COL WIDTH=131*> <COL WIDTH=231>
<COL WIDTH=125*> <COL WIDTH=332>
<TR VALIGN=TOP> <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> <P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_NONE</I></FONT></P>
</TD> </TD>
<TD WIDTH=49%> <TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal"> <P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Do not transmit any repair requests for the newly received object.</P> Do not transmit any repair requests for the newly received object.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <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> <P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_INFO_ONLY</I></FONT></P>
</TD> </TD>
<TD WIDTH=49%> <TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal"> <P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Transmit repair requests for NORM_INFO content only as needed.</P> Transmit repair requests for NORM_INFO content only as needed.</P>
</TD> </TD>
</TR> </TR>
<TR VALIGN=TOP> <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> <P CLASS="western" STYLE="margin-left: 0.5in; font-style: normal"><FONT FACE="Courier"><I>NORM_NACK_NORMAL</I></FONT></P>
</TD> </TD>
<TD WIDTH=49%> <TD WIDTH=332>
<P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal"> <P CLASS="western" STYLE="margin-left: 0.02in; font-style: normal">
Transmit repair requests for entire object as needed.</P> Transmit repair requests for entire object as needed.</P>
</TD> </TD>

Binary file not shown.

View File

@ -1,5 +1,18 @@
NORM Version History 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 Version 1.2b9
============= =============
- Fixed bugs with NormServerNode::retrieval_pool mgmnt - Fixed bugs with NormServerNode::retrieval_pool mgmnt

View File

@ -2,6 +2,12 @@
#include "normApi.h" #include "normApi.h"
#include "normSession.h" #include "normSession.h"
#ifdef WIN32
#ifndef _WIN32_WCE
#include <io.h> // for _mktemp()
#endif // !_WIN32_WCE
#endif // WIN32
// const defs // const defs
const NormInstanceHandle NORM_INSTANCE_INVALID = ((NormInstanceHandle)0); const NormInstanceHandle NORM_INSTANCE_INVALID = ((NormInstanceHandle)0);
const NormSessionHandle NORM_SESSION_INVALID = ((NormSessionHandle)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 NormNodeId NORM_NODE_ANY = ((NormNodeId)0xffffffff);
const NormObjectHandle NORM_OBJECT_INVALID = ((NormObjectHandle)0); 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 /** The "NormInstance" class is a C++ helper class that keeps
* state for an instance of the NORM API. It acts as a * state for an instance of the NORM API. It acts as a
* "go between" the API's procedural function calls and * "go between" the API's procedural function calls and
@ -27,7 +35,7 @@ class NormInstance : public NormController
class NormServerNode* server, class NormServerNode* server,
class NormObject* object); class NormObject* object);
bool Startup(); bool Startup(bool priorityBoost = false);
void Shutdown(); void Shutdown();
bool WaitForEvent(); bool WaitForEvent();
@ -250,9 +258,38 @@ void NormInstance::Notify(NormController::Event event,
{ {
char fileName[PATH_MAX]; char fileName[PATH_MAX];
strncpy(fileName, rx_cache_path, 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
#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)) if (!_mktemp(fileName))
#endif // if/else _WIN32_WCE
#else #else
int fd = mkstemp(fileName); int fd = mkstemp(fileName);
if (fd >= 0) if (fd >= 0)
@ -263,7 +300,7 @@ void NormInstance::Notify(NormController::Event event,
#endif // if/else WIN32 #endif // if/else WIN32
{ {
DMSG(0, "NormInstance::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n", DMSG(0, "NormInstance::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n",
strerror(errno)); GetErrorString());
} }
if (!static_cast<NormFileObject*>(object)->Accept(fileName)) if (!static_cast<NormFileObject*>(object)->Accept(fileName))
{ {
@ -401,6 +438,11 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
// reset update event notification // reset update event notification
((NormObject*)n->event.object)->SetNotifyOnUpdate(true); ((NormObject*)n->event.object)->SetNotifyOnUpdate(true);
break; 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: default:
break; break;
} }
@ -441,7 +483,7 @@ bool NormInstance::WaitForEvent()
} // end NormInstance::WaitForEvent() } // end NormInstance::WaitForEvent()
bool NormInstance::Startup() bool NormInstance::Startup(bool priorityBoost)
{ {
// 1) Create descriptor to use for event notification // 1) Create descriptor to use for event notification
#ifdef WIN32 #ifdef WIN32
@ -469,7 +511,7 @@ bool NormInstance::Startup()
} }
#endif // if/else WIN32/UNIX #endif // if/else WIN32/UNIX
// 2) Start thread // 2) Start thread
return dispatcher.StartThread(); return dispatcher.StartThread(priorityBoost);
} // end NormInstance::Startup() } // end NormInstance::Startup()
void NormInstance::Shutdown() void NormInstance::Shutdown()
@ -554,12 +596,12 @@ void NormInstance::Shutdown()
/** NORM API Initialization */ /** NORM API Initialization */
NormInstanceHandle NormCreateInstance() NormInstanceHandle NormCreateInstance(bool priorityBoost)
{ {
NormInstance* normInstance = new NormInstance; NormInstance* normInstance = new NormInstance;
if (normInstance) if (normInstance)
{ {
if (normInstance->Startup()) if (normInstance->Startup(priorityBoost))
return ((NormInstanceHandle)normInstance); return ((NormInstanceHandle)normInstance);
else else
delete normInstance; delete normInstance;
@ -582,6 +624,15 @@ bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
return false; return false;
} // end NormSetCacheDirectory() } // 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 NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent)
{ {
bool result = false; bool result = false;
@ -636,6 +687,37 @@ void NormDestroySession(NormSessionHandle sessionHandle)
} }
} // end NormDestroySession() } // 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) NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
{ {
NormSession* session = (NormSession*)sessionHandle; NormSession* session = (NormSession*)sessionHandle;
@ -645,6 +727,21 @@ NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle)
return NORM_NODE_NONE; return NORM_NODE_NONE;
} // end NormGetLocalNodeId() } // 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, bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
const char* interfaceName) const char* interfaceName)
{ {
@ -774,6 +871,21 @@ void NormSetTransmitRate(NormSessionHandle sessionHandle,
} }
} // end NormSetTransmitRate() } // 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) void NormSetCongestionControl(NormSessionHandle sessionHandle, bool enable)
{ {
NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle); NormInstance* instance = NormInstance::GetInstanceFromSession(sessionHandle);
@ -936,7 +1048,13 @@ void NormStreamFlush(NormObjectHandle streamHandle,
{ {
NormStreamObject* stream = NormStreamObject* stream =
static_cast<NormStreamObject*>((NormObject*)streamHandle); 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(); instance->dispatcher.ResumeThread();
} }
} // end NormStreamFlush() } // end NormStreamFlush()
@ -1036,6 +1154,21 @@ void NormStopReceiver(NormSessionHandle sessionHandle)
} }
} // end NormStopReceiver() } // 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, void NormSetSilentReceiver(NormSessionHandle sessionHandle,
bool silent) bool silent)
{ {
@ -1293,6 +1426,37 @@ NormNodeId NormNodeGetId(NormNodeHandle nodeHandle)
return NORM_NODE_NONE; return NORM_NODE_NONE;
} // end NormNodeGetId() } // 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) void NormNodeRetain(NormNodeHandle nodeHandle)
{ {
if (NORM_NODE_INVALID != nodeHandle) if (NORM_NODE_INVALID != nodeHandle)

View File

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

View File

@ -6,8 +6,6 @@
#include "normPostProcess.h" #include "normPostProcess.h"
#include <stdio.h> // for stdout/stderr printouts #include <stdio.h> // for stdout/stderr printouts
#include <signal.h> // for SIGTERM/SIGINT handling
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> // for "isspace()" #include <ctype.h> // for "isspace()"
@ -419,7 +417,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
if (!(address = new char[len+1])) if (!(address = new char[len+1]))
{ {
DMSG(0, "NormApp::OnCommand(address) allocation error:%s\n", DMSG(0, "NormApp::OnCommand(address) allocation error:%s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
strcpy(address, val); strcpy(address, val);
@ -526,7 +524,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(input = fopen(val, "rb"))) else if (!(input = fopen(val, "rb")))
{ {
DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n", DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
input_index = input_length = 0; input_index = input_length = 0;
@ -546,7 +544,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(output = fopen(val, "wb"))) else if (!(output = fopen(val, "wb")))
{ {
DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n", DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
output_messaging = false; output_messaging = false;
@ -562,7 +560,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(input = fopen(val, "rb"))) else if (!(input = fopen(val, "rb")))
{ {
DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n", DMSG(0, "NormApp::OnCommand(input) fopen() error: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
input_index = input_length = 0; input_index = input_length = 0;
@ -582,7 +580,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
else if (!(output = fopen(val, "wb"))) else if (!(output = fopen(val, "wb")))
{ {
DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n", DMSG(0, "NormApp::OnCommand(output) fopen() error: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
output_messaging = true; output_messaging = true;
@ -641,7 +639,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
if (!(rx_cache_path = new char[length])) if (!(rx_cache_path = new char[length]))
{ {
DMSG(0, "NormApp::OnCommand(rxcachedir) alloc error: %s\n", DMSG(0, "NormApp::OnCommand(rxcachedir) alloc error: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
strcpy(rx_cache_path, val); strcpy(rx_cache_path, val);
@ -979,6 +977,7 @@ void NormApp::OnInputReady()
} }
else if (ferror(input)) else if (ferror(input))
{ {
#ifndef WIN32 // no Win32 stream support yet
switch (errno) switch (errno)
{ {
case EINTR: case EINTR:
@ -988,9 +987,10 @@ void NormApp::OnInputReady()
inputStarved = true; inputStarved = true;
break; break;
default: default:
DMSG(0, "norm: input error:%s\n", strerror(errno)); DMSG(0, "norm: input error:%s\n", GetErrorString());
break; break;
} }
#endif // !WIN32
clearerr(input); clearerr(input);
} }
} }
@ -1123,9 +1123,37 @@ void NormApp::Notify(NormController::Event event,
// (TBD) Manage recv file name collisions, etc ... // (TBD) Manage recv file name collisions, etc ...
char fileName[PATH_MAX]; char fileName[PATH_MAX];
strcpy(fileName, rx_cache_path); strcpy(fileName, rx_cache_path);
size_t catMax = strlen(fileName);
if (catMax > PATH_MAX)
catMax = 0;
else
catMax = PATH_MAX - catMax;
strcat(fileName, "normTempXXXXXX"); strcat(fileName, "normTempXXXXXX");
#ifdef WIN32 #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)) if (!_mktemp(fileName))
#endif // if/else _WIN32_WCE
#else #else
int fd = mkstemp(fileName); int fd = mkstemp(fileName);
if (fd >= 0) if (fd >= 0)
@ -1136,7 +1164,7 @@ void NormApp::Notify(NormController::Event event,
#endif // if/else WIN32 #endif // if/else WIN32
{ {
DMSG(0, "NormApp::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n", DMSG(0, "NormApp::Notify(RX_OBJECT_NEW) Warning: mkstemp() error: %s\n",
strerror(errno)); GetErrorString());
} }
if (!static_cast<NormFileObject*>(object)->Accept(fileName)) if (!static_cast<NormFileObject*>(object)->Accept(fileName))
{ {
@ -1305,14 +1333,16 @@ void NormApp::Notify(NormController::Event event,
{ {
if (ferror(output)) if (ferror(output))
{ {
#ifndef WIN32 // no stream support in this app for Win32
if (EINTR == errno) if (EINTR == errno)
{ {
clearerr(output); clearerr(output);
continue; continue;
} }
else else
#endif // !WIN32
{ {
DMSG(0, "norm: output error:%s\n", strerror(errno)); DMSG(0, "norm: output error:%s\n", GetErrorString());
clearerr(output); clearerr(output);
break; 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 <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include "normEncoder.h" #include "normEncoder.h"
#include "galois.h" // for Galois math routines #include "galois.h" // for Galois math routines
@ -78,7 +77,7 @@ bool NormEncoder::Init(int numParity, int vecSizeMax)
if(!(scratch = new unsigned char[vecSizeMax])) if(!(scratch = new unsigned char[vecSizeMax]))
{ {
DMSG(0, "NormEncoder: Error allocating memory for encoder scratch space: %s\n", DMSG(0, "NormEncoder: Error allocating memory for encoder scratch space: %s\n",
strerror(errno)); GetErrorString());
Destroy(); Destroy();
return false; return false;
} }
@ -110,14 +109,14 @@ bool NormEncoder::CreateGeneratorPolynomial()
if(!(genPoly = new unsigned char[npar+1])) if(!(genPoly = new unsigned char[npar+1]))
{ {
DMSG(0, "NormEncoder: Error allocating memory for generator polynomial: %s\n", DMSG(0, "NormEncoder: Error allocating memory for generator polynomial: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
/* Allocate memory for temporary polynomial arrays */ /* Allocate memory for temporary polynomial arrays */
if(!(tp = new unsigned char[2*degree])) if(!(tp = new unsigned char[2*degree]))
{ {
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n", DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno)); GetErrorString());
delete genPoly; delete genPoly;
return false; return false;
} }
@ -126,7 +125,7 @@ bool NormEncoder::CreateGeneratorPolynomial()
delete tp; delete tp;
delete genPoly; delete genPoly;
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n", DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
if(!(tp2 = new unsigned char[2*degree])) if(!(tp2 = new unsigned char[2*degree]))
@ -135,7 +134,7 @@ bool NormEncoder::CreateGeneratorPolynomial()
delete tp; delete tp;
delete genPoly; delete genPoly;
DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n", DMSG(0, "NormEncoder: Error allocating memory while computing genpoly: %s\n",
strerror(errno)); GetErrorString());
return false; return false;
} }
// multiply (x + a^n) for n = 1 to npar // 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])) if(!(Lambda = new unsigned char[2*npar]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for Lambda: %s\n", DMSG(0, "NormDecoder: Error allocating memory for Lambda: %s\n",
strerror(errno)); GetErrorString());
return(false); return(false);
} }
@ -255,7 +254,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(sVec = new unsigned char*[npar])) if(!(sVec = new unsigned char*[npar]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for sVec ptr: %s\n", DMSG(0, "NormDecoder: Error allocating memory for sVec ptr: %s\n",
strerror(errno)); GetErrorString());
Destroy(); Destroy();
return(false); return(false);
} }
@ -265,7 +264,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(sVec[i] = new unsigned char[vecSizeMax])) if(!(sVec[i] = new unsigned char[vecSizeMax]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for new sVec: %s\n", DMSG(0, "NormDecoder: Error allocating memory for new sVec: %s\n",
strerror(errno)); GetErrorString());
Destroy(); Destroy();
return(false); return(false);
} }
@ -275,7 +274,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(oVec = new unsigned char*[npar])) if(!(oVec = new unsigned char*[npar]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for new oVec ptr: %s\n", DMSG(0, "NormDecoder: Error allocating memory for new oVec ptr: %s\n",
strerror(errno)); GetErrorString());
Destroy(); Destroy();
return(false); return(false);
} }
@ -285,7 +284,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if(!(oVec[i] = new unsigned char[vecSizeMax])) if(!(oVec[i] = new unsigned char[vecSizeMax]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for new oVec: %s", DMSG(0, "NormDecoder: Error allocating memory for new oVec: %s",
strerror(errno)); GetErrorString());
Destroy(); Destroy();
return(false); return(false);
} }
@ -294,7 +293,7 @@ bool NormDecoder::Init(int numParity, int vecSizeMax)
if (!(scratch = new unsigned char[vecSizeMax])) if (!(scratch = new unsigned char[vecSizeMax]))
{ {
DMSG(0, "NormDecoder: Error allocating memory for scratch space: %s", DMSG(0, "NormDecoder: Error allocating memory for scratch space: %s",
strerror(errno)); GetErrorString());
} }
memset(scratch, 0, vecSizeMax*sizeof(unsigned char)); memset(scratch, 0, vecSizeMax*sizeof(unsigned char));
return(true); return(true);

View File

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

View File

@ -7,18 +7,39 @@
// class is provided to manage a list of files. // class is provided to manage a list of files.
#ifdef WIN32 #ifdef WIN32
#include <io.h> //#include <io.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif // if/else WIN32 #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/types.h>
#include <sys/stat.h> #endif // if/else _WIN32_WCE
// From PROTOLIB // From PROTOLIB
#include "protokit.h" // for Protolib stuff #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 class NormFile
{ {
@ -33,7 +54,14 @@ class NormFile
bool Rename(const char* oldName, const char* newName); bool Rename(const char* oldName, const char* newName);
bool Unlink(const char *path); bool Unlink(const char *path);
void Close(); 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 Read(char* buffer, int len);
int Write(const char* buffer, int len); int Write(const char* buffer, int len);
bool Seek(off_t theOffset); bool Seek(off_t theOffset);
@ -49,7 +77,13 @@ class NormFile
static bool Exists(const char* path) static bool Exists(const char* path)
{ {
#ifdef WIN32 #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)); return (0xFFFFFFFF != GetFileAttributes(path));
#endif // if/else _UNICODE
#else #else
return (0 == access(path, F_OK)); return (0 == access(path, F_OK));
#endif // if/else WIN32 #endif // if/else WIN32
@ -58,7 +92,13 @@ class NormFile
static bool IsWritable(const char* path) static bool IsWritable(const char* path)
{ {
#ifdef WIN32 #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); DWORD attr = GetFileAttributes(path);
#endif // if/else _UNICODE
return ((0xFFFFFFFF == attr) ? return ((0xFFFFFFFF == attr) ?
false : (0 == (attr & FILE_ATTRIBUTE_READONLY))); false : (0 == (attr & FILE_ATTRIBUTE_READONLY)));
#else #else
@ -69,7 +109,11 @@ class NormFile
// Members // Members
private: private:
#ifdef _WIN32_WCE
FILE* file_ptr;
#else
int fd; int fd;
#endif // if/else _WIN32_WCE
int flags; int flags;
off_t offset; off_t offset;
}; // end class NormFile }; // end class NormFile

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
#define _NORM_SEGMENT #define _NORM_SEGMENT
#include "normMessage.h" #include "normMessage.h"
#include "normBitmask.h" #include "protoBitmask.h"
// Norm uses preallocated (or dynamically allocated) pools of // Norm uses preallocated (or dynamically allocated) pools of
// segments (vectors) for different buffering purposes // segments (vectors) for different buffering purposes
@ -231,19 +231,19 @@ class NormBlock
void EmptyToPool(NormSegmentPool& segmentPool); void EmptyToPool(NormSegmentPool& segmentPool);
private: private:
NormBlockId id; NormBlockId id;
UINT16 size; UINT16 size;
char** segment_table; char** segment_table;
int flags; int flags;
UINT16 erasure_count; UINT16 erasure_count;
UINT16 parity_count; UINT16 parity_count;
UINT16 parity_offset; UINT16 parity_offset;
NormBitmask pending_mask; ProtoBitmask pending_mask;
NormBitmask repair_mask; ProtoBitmask repair_mask;
NormBlock* next; NormBlock* next;
}; // end class NormBlock }; // end class NormBlock
class NormBlockPool class NormBlockPool

View File

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

View File

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

View File

@ -32,28 +32,42 @@ int main(int argc, char* argv[])
"224.1.2.3", "224.1.2.3",
6003, 6003,
NORM_NODE_ANY); NORM_NODE_ANY);
// Uncomment to turn on debug NORM message tracing
//NormSetMessageTrace(session, true); //NormSetMessageTrace(session, true);
//NormSetTxLoss(session, 1.0); // 10% packet loss //NormSetTxLoss(session, 1.0); // 10% packet loss
NormSetGrttEstimate(session, 0.001); // 1 msec initial grtt 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); 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 // Uncomment to receive your own traffic
//NormSetLoopback(session, true); NormSetLoopback(session, true);
// Uncomment this line to participate as a receiver // Uncomment this line to participate as a receiver
//NormStartReceiver(session, 1024*1024); //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 // Uncomment to enable TCP-friendly congestion control
//NormSetCongestionControl(session, true); //NormSetCongestionControl(session, true);
// Uncomment the following line to start sender // Uncomment the following line to start sender
NormStartSender(session, 4096*1024, 1400, 64, 0); 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)); NormAddAckingNode(session, NormGetLocalNodeId(session));
@ -67,8 +81,7 @@ int main(int argc, char* argv[])
// NORM_FLUSH_PASSIVE automatically flushes full writes to // NORM_FLUSH_PASSIVE automatically flushes full writes to
// the stream. // the stream.
NormStreamSetAutoFlush(stream, NORM_FLUSH_PASSIVE); NormStreamSetAutoFlush(stream, NORM_FLUSH_PASSIVE);
// Some variable for stream input/output // Some variable for stream input/output
char txBuffer[8192], rxBuffer[8192]; char txBuffer[8192], rxBuffer[8192];
@ -88,10 +101,10 @@ int main(int argc, char* argv[])
{ {
switch (theEvent.type) switch (theEvent.type)
{ {
case NORM_TX_QUEUE_VACANCY:
// TRACE("NORM_TX_QUEUE_VACANCY ...\n");
case NORM_TX_QUEUE_EMPTY: case NORM_TX_QUEUE_EMPTY:
//TRACE("NORM_TX_QUEUE_EMPTY ...\n"); //TRACE("NORM_TX_QUEUE_EMPTY ...\n");
case NORM_TX_QUEUE_VACANCY:
//TRACE("NORM_TX_QUEUE_VACANCY ...\n");
if (NORM_OBJECT_INVALID != stream) if (NORM_OBJECT_INVALID != stream)
{ {
@ -115,7 +128,7 @@ int main(int argc, char* argv[])
// Instead of "NormStreamSetFlushMode(stream, NORM_FLUSH_PASSIVE)" above // Instead of "NormStreamSetFlushMode(stream, NORM_FLUSH_PASSIVE)" above
// and "NormStreamMarkEom()" here, I could have used // and "NormStreamMarkEom()" here, I could have used
// "NormStreamFlush(stream, true)" here to perform explicit flushing // "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 // for apps where big stream messages need to be written with
// multiple calls to "NormStreamWrite()" // multiple calls to "NormStreamWrite()"
NormStreamMarkEom(stream); NormStreamMarkEom(stream);

View File

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

View File

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

Binary file not shown.

View File

@ -104,21 +104,6 @@ SOURCE=..\common\normApi.cpp
# End Source File # End Source File
# Begin 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 SOURCE=..\common\normEncoder.cpp
!IF "$(CFG)" == "NormLib - Win32 Release" !IF "$(CFG)" == "NormLib - Win32 Release"

View File

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