v1.2b5
parent
f451a006f6
commit
700519ec12
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -1,9 +1,14 @@
|
||||||
NORM Version History
|
NORM Version History
|
||||||
|
|
||||||
|
Version 1.2b5
|
||||||
|
=============
|
||||||
|
- Initial release with theoretically-working API
|
||||||
|
(including "Norm Developer's Guide!")
|
||||||
|
|
||||||
Version 1.2b4
|
Version 1.2b4
|
||||||
=============
|
=============
|
||||||
- Finally remembered to update this file!
|
- Finally remembered to update this file!
|
||||||
- Added "help" command to "norm" demo app (Thanks Marinho Barcellos)
|
- Added "help" command to "norm" demo app (Thanks Marinho Barcellos!)
|
||||||
- New rxbuffer mgmnt scheme to better use limited buffer space.
|
- New rxbuffer mgmnt scheme to better use limited buffer space.
|
||||||
- Removed explicit rate limit on receiver feedback messages
|
- Removed explicit rate limit on receiver feedback messages
|
||||||
- API more complete and established better API naming conventions
|
- API more complete and established better API naming conventions
|
||||||
|
|
@ -12,6 +17,7 @@ Version 1.2b4
|
||||||
- NORM RFC 3940 was released and this version is in compliance.
|
- NORM RFC 3940 was released and this version is in compliance.
|
||||||
- Added optional positive acknowledgements for sender-defined
|
- Added optional positive acknowledgements for sender-defined
|
||||||
"watermarks".
|
"watermarks".
|
||||||
|
- Fixed multicast leave problem when interfaceName was used for join
|
||||||
|
|
||||||
Version 1.1b9
|
Version 1.1b9
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
390
common/normApi.h
390
common/normApi.h
|
|
@ -6,6 +6,8 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
#include <sys/types.h> // for "off_t" type
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// IMPORTANT NOTICE
|
// IMPORTANT NOTICE
|
||||||
// The NORM API is _very_ much in a developmental phase
|
// The NORM API is _very_ much in a developmental phase
|
||||||
|
|
@ -18,106 +20,27 @@
|
||||||
// is removed, the API shouldn't be considered final.
|
// is removed, the API shouldn't be considered final.
|
||||||
|
|
||||||
|
|
||||||
|
/** NORM API Data Types and Constants
|
||||||
|
* These are data types and constants defined
|
||||||
|
* for the NORM API
|
||||||
|
*/
|
||||||
|
|
||||||
typedef const void* NormInstanceHandle;
|
typedef const void* NormInstanceHandle;
|
||||||
extern const NormInstanceHandle NORM_INSTANCE_INVALID;
|
extern const NormInstanceHandle NORM_INSTANCE_INVALID;
|
||||||
|
|
||||||
NormInstanceHandle NormCreateInstance();
|
|
||||||
void NormDestroyInstance(NormInstanceHandle instanceHandle);
|
|
||||||
|
|
||||||
// NORM session creation and control
|
|
||||||
typedef const void* NormSessionHandle;
|
typedef const void* NormSessionHandle;
|
||||||
extern const NormSessionHandle NORM_SESSION_INVALID;
|
extern const NormSessionHandle NORM_SESSION_INVALID;
|
||||||
|
|
||||||
|
typedef const void* NormNodeHandle;
|
||||||
|
extern const NormNodeHandle NORM_NODE_INVALID;
|
||||||
typedef unsigned long NormNodeId;
|
typedef unsigned long NormNodeId;
|
||||||
extern const NormNodeId NORM_NODE_NONE;
|
extern const NormNodeId NORM_NODE_NONE;
|
||||||
extern const NormNodeId NORM_NODE_ANY;
|
extern const NormNodeId NORM_NODE_ANY;
|
||||||
|
|
||||||
NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
|
|
||||||
const char* sessionAddress,
|
|
||||||
unsigned short sessionPort,
|
|
||||||
NormNodeId localNodeId);
|
|
||||||
|
|
||||||
void NormDestroySession(NormSessionHandle sessionHandle);
|
|
||||||
|
|
||||||
// Session management and parameters
|
|
||||||
|
|
||||||
void NormSetTransmitRate(NormSessionHandle sessionHandle,
|
|
||||||
double bitsPerSecond);
|
|
||||||
|
|
||||||
void NormSetGrttEstimate(NormSessionHandle sessionHandle,
|
|
||||||
double grttEstimate);
|
|
||||||
|
|
||||||
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
|
|
||||||
|
|
||||||
bool NormSetLoopback(NormSessionHandle sessionHandle, bool state);
|
|
||||||
|
|
||||||
// Debug parameters
|
|
||||||
void NormSetMessageTrace(NormSessionHandle sessionHandle, bool state);
|
|
||||||
void NormSetTxLoss(NormSessionHandle sessionHandle, double percent);
|
|
||||||
void NormSetRxLoss(NormSessionHandle sessionHandle, double percent);
|
|
||||||
|
|
||||||
// Sender control & parameters
|
|
||||||
bool NormStartSender(NormSessionHandle sessionHandle,
|
|
||||||
unsigned long bufferSpace,
|
|
||||||
unsigned short segmentSize,
|
|
||||||
unsigned char numData,
|
|
||||||
unsigned char numParity);
|
|
||||||
|
|
||||||
void NormStopSender(NormSessionHandle sessionHandle);
|
|
||||||
|
|
||||||
bool NormAddAckingNode(NormSessionHandle sessionHandle,
|
|
||||||
NormNodeId nodeId);
|
|
||||||
|
|
||||||
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
|
||||||
NormNodeId nodeId);
|
|
||||||
|
|
||||||
|
|
||||||
// Receiver control & parameters
|
|
||||||
bool NormStartReceiver(NormSessionHandle sessionHandle,
|
|
||||||
unsigned long bufferSpace);
|
|
||||||
|
|
||||||
void NormStopReceiver(NormSessionHandle sessionHandle);
|
|
||||||
|
|
||||||
void NormSetDefaultUnicastNack(NormSessionHandle sessionHandle,
|
|
||||||
bool state);
|
|
||||||
|
|
||||||
typedef const void* NormNodeHandle;
|
|
||||||
extern const NormNodeHandle NORM_NODE_INVALID;
|
|
||||||
typedef const void* NormObjectHandle;
|
typedef const void* NormObjectHandle;
|
||||||
extern const NormObjectHandle NORM_OBJECT_INVALID;
|
extern const NormObjectHandle NORM_OBJECT_INVALID;
|
||||||
typedef unsigned short NormObjectTransportId;
|
typedef unsigned short NormObjectTransportId;
|
||||||
|
|
||||||
enum NormNackingMode
|
|
||||||
{
|
|
||||||
NORM_NACK_NONE,
|
|
||||||
NORM_NACK_INFO_ONLY,
|
|
||||||
NORM_NACK_NORMAL
|
|
||||||
};
|
|
||||||
|
|
||||||
void NormSetDefaultNackingMode(NormSessionHandle sessionHandle,
|
|
||||||
NormNackingMode nackingMode);
|
|
||||||
|
|
||||||
enum NormRepairBoundary
|
|
||||||
{
|
|
||||||
NORM_BOUNDARY_BLOCK,
|
|
||||||
NORM_BOUNDARY_OBJECT
|
|
||||||
};
|
|
||||||
|
|
||||||
void NormSetDefaultRepairBoundary(NormSessionHandle sessionHandle,
|
|
||||||
NormRepairBoundary repairBoundary);
|
|
||||||
|
|
||||||
NormRepairBoundary NormNodeGetRepairBoundary(NormNodeHandle nodeHandle);
|
|
||||||
|
|
||||||
void NormNodeSetRepairBoundary(NormNodeHandle nodeHandle,
|
|
||||||
NormRepairBoundary repairBoundary);
|
|
||||||
|
|
||||||
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle);
|
|
||||||
|
|
||||||
void NormNodeSetNackingMode(NormNodeHandle nodeHandle,
|
|
||||||
NormNackingMode nackingMode);
|
|
||||||
|
|
||||||
|
|
||||||
// General NormObject functions
|
|
||||||
|
|
||||||
enum NormObjectType
|
enum NormObjectType
|
||||||
{
|
{
|
||||||
NORM_OBJECT_NONE,
|
NORM_OBJECT_NONE,
|
||||||
|
|
@ -126,95 +49,27 @@ enum NormObjectType
|
||||||
NORM_OBJECT_STREAM
|
NORM_OBJECT_STREAM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
NormObjectType NormObjectGetType(NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
|
|
||||||
bool NormObjectGetInfo(NormObjectHandle objectHandle,
|
|
||||||
char* infoBuffer,
|
|
||||||
unsigned short* infoLen);
|
|
||||||
|
|
||||||
NormObjectTransportId NormObjectGetTransportId(NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
void NormObjectCancel(NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
|
|
||||||
void NormObjectReNormObjectRetaintain(NormObjectHandle objectHandle);
|
|
||||||
void NormObjectRelease(NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
|
|
||||||
// Receiver-only NormObject functions
|
|
||||||
NormNackingMode NormObjectGetNackingMode(NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
void NormObjectSetNackingMode(NormObjectHandle objectHandle,
|
|
||||||
NormNackingMode nackingMode);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sender-only NormObject functions
|
|
||||||
bool NormSetWatermark(NormSessionHandle sessionHandle,
|
|
||||||
NormObjectHandle objectHandle);
|
|
||||||
|
|
||||||
|
|
||||||
// NormStreamObject functions
|
|
||||||
|
|
||||||
NormObjectHandle NormStreamOpen(NormSessionHandle sessionHandle,
|
|
||||||
unsigned long bufferSize);
|
|
||||||
|
|
||||||
void NormStreamClose(NormObjectHandle streamHandle);
|
|
||||||
|
|
||||||
enum NormFlushMode
|
enum NormFlushMode
|
||||||
{
|
{
|
||||||
NORM_FLUSH_NONE,
|
NORM_FLUSH_NONE,
|
||||||
NORM_FLUSH_PASSIVE,
|
NORM_FLUSH_PASSIVE,
|
||||||
NORM_FLUSH_ACTIVE
|
NORM_FLUSH_ACTIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void NormStreamSetFlushMode(NormObjectHandle streamHandle,
|
enum NormNackingMode
|
||||||
NormFlushMode flushMode);
|
{
|
||||||
|
NORM_NACK_NONE,
|
||||||
void NormStreamSetPushMode(NormObjectHandle streamHandle,
|
NORM_NACK_INFO_ONLY,
|
||||||
bool state);
|
NORM_NACK_NORMAL
|
||||||
|
};
|
||||||
unsigned int NormStreamWrite(NormObjectHandle streamHandle,
|
|
||||||
const char* buffer,
|
enum NormRepairBoundary
|
||||||
unsigned int numBytes);
|
{
|
||||||
|
NORM_BOUNDARY_BLOCK,
|
||||||
void NormStreamFlush(NormObjectHandle streamHandle, bool eom = false);
|
NORM_BOUNDARY_OBJECT
|
||||||
|
};
|
||||||
void NormStreamMarkEom(NormObjectHandle streamHandle);
|
|
||||||
|
|
||||||
bool NormStreamRead(NormObjectHandle streamHandle,
|
|
||||||
char* buffer,
|
|
||||||
unsigned int* numBytes);
|
|
||||||
|
|
||||||
bool NormStreamSeekMsgStart(NormObjectHandle streamHandle);
|
|
||||||
|
|
||||||
// NormFileObject Functions
|
|
||||||
NormObjectHandle NormFileEnqueue(NormSessionHandle sessionHandle,
|
|
||||||
const char* fileName,
|
|
||||||
const char* infoPtr = (const char*)0,
|
|
||||||
unsigned int infoLen = 0);
|
|
||||||
|
|
||||||
bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
|
|
||||||
const char* cachePath);
|
|
||||||
|
|
||||||
bool NormFileGetName(NormObjectHandle fileHandle,
|
|
||||||
char* nameBuffer,
|
|
||||||
unsigned int bufferLen);
|
|
||||||
|
|
||||||
bool NormFileRename(NormObjectHandle fileHandle,
|
|
||||||
const char* fileName);
|
|
||||||
|
|
||||||
// NormDataObject Functions
|
|
||||||
bool NormDataEnqueue(const char* dataPtr,
|
|
||||||
unsigned long dataLen,
|
|
||||||
const char* infoPtr = (const char*)0,
|
|
||||||
unsigned int infoLen = 0);
|
|
||||||
|
|
||||||
// NORM Event Notification Routines
|
|
||||||
|
|
||||||
enum NormEventType
|
enum NormEventType
|
||||||
{
|
{
|
||||||
NORM_EVENT_INVALID = 0,
|
NORM_EVENT_INVALID = 0,
|
||||||
|
|
@ -224,11 +79,12 @@ enum NormEventType
|
||||||
NORM_TX_OBJECT_PURGED,
|
NORM_TX_OBJECT_PURGED,
|
||||||
NORM_LOCAL_SERVER_CLOSED,
|
NORM_LOCAL_SERVER_CLOSED,
|
||||||
NORM_REMOTE_SERVER_NEW,
|
NORM_REMOTE_SERVER_NEW,
|
||||||
NORM_REMOTE_SERVER_INACTIVE,
|
|
||||||
NORM_REMOTE_SERVER_ACTIVE,
|
NORM_REMOTE_SERVER_ACTIVE,
|
||||||
|
NORM_REMOTE_SERVER_INACTIVE,
|
||||||
|
NORM_REMOTE_SERVER_PURGED,
|
||||||
NORM_RX_OBJECT_NEW,
|
NORM_RX_OBJECT_NEW,
|
||||||
NORM_RX_OBJECT_INFO,
|
NORM_RX_OBJECT_INFO,
|
||||||
NORM_RX_OBJECT_UPDATE,
|
NORM_RX_OBJECT_UPDATED,
|
||||||
NORM_RX_OBJECT_COMPLETED,
|
NORM_RX_OBJECT_COMPLETED,
|
||||||
NORM_RX_OBJECT_ABORTED
|
NORM_RX_OBJECT_ABORTED
|
||||||
};
|
};
|
||||||
|
|
@ -240,7 +96,17 @@ typedef struct
|
||||||
NormNodeHandle sender;
|
NormNodeHandle sender;
|
||||||
NormObjectHandle object;
|
NormObjectHandle object;
|
||||||
} NormEvent;
|
} NormEvent;
|
||||||
|
|
||||||
|
|
||||||
|
/** NORM API General Initialization and Operation Functions */
|
||||||
|
|
||||||
|
NormInstanceHandle NormCreateInstance();
|
||||||
|
|
||||||
|
void NormDestroyInstance(NormInstanceHandle instanceHandle);
|
||||||
|
|
||||||
|
// This MUST be set to enable NORM_OBJECT_FILE reception!
|
||||||
|
bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
|
||||||
|
const char* cachePath);
|
||||||
|
|
||||||
// This call blocks until the next NormEvent is ready unless asynchronous
|
// This call blocks until the next NormEvent is ready unless asynchronous
|
||||||
// notification is used (see below)
|
// notification is used (see below)
|
||||||
|
|
@ -252,7 +118,7 @@ bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent);
|
||||||
// with system calls like "WaitForSingleEvent()", and on Unix the
|
// with system calls like "WaitForSingleEvent()", and on Unix the
|
||||||
// returned descriptor can be used in a "select()" call. If this type
|
// returned descriptor can be used in a "select()" call. If this type
|
||||||
// of asynchronous notification is used, calls to "NormGetNextEvent()" will
|
// of asynchronous notification is used, calls to "NormGetNextEvent()" will
|
||||||
// not block.
|
// not block when the notification is posted.
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
typedef HANDLE NormDescriptor;
|
typedef HANDLE NormDescriptor;
|
||||||
|
|
@ -261,4 +127,184 @@ typedef int NormDescriptor;
|
||||||
#endif // if/else WIN32/UNIX
|
#endif // if/else WIN32/UNIX
|
||||||
NormDescriptor NormGetDescriptor(NormInstanceHandle instanceHandle);
|
NormDescriptor NormGetDescriptor(NormInstanceHandle instanceHandle);
|
||||||
|
|
||||||
|
/** NORM Session Creation and Control Functions */
|
||||||
|
|
||||||
|
NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
|
||||||
|
const char* sessionAddress,
|
||||||
|
unsigned short sessionPort,
|
||||||
|
NormNodeId localNodeId);
|
||||||
|
|
||||||
|
void NormDestroySession(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
|
||||||
|
const char* interfaceName);
|
||||||
|
|
||||||
|
bool NormSetTTL(NormSessionHandle sessionHandle,
|
||||||
|
unsigned char ttl);
|
||||||
|
|
||||||
|
bool NormSetTOS(NormSessionHandle sessionHandle,
|
||||||
|
unsigned char tos);
|
||||||
|
|
||||||
|
bool NormSetLoopback(NormSessionHandle sessionHandle,
|
||||||
|
bool loopback);
|
||||||
|
|
||||||
|
// Special functions for debug support
|
||||||
|
void NormSetMessageTrace(NormSessionHandle sessionHandle, bool state);
|
||||||
|
void NormSetTxLoss(NormSessionHandle sessionHandle, double percent);
|
||||||
|
void NormSetRxLoss(NormSessionHandle sessionHandle, double percent);
|
||||||
|
|
||||||
|
|
||||||
|
/** NORM Sender Functions */
|
||||||
|
|
||||||
|
bool NormStartSender(NormSessionHandle sessionHandle,
|
||||||
|
unsigned long bufferSpace,
|
||||||
|
unsigned short segmentSize,
|
||||||
|
unsigned char numData,
|
||||||
|
unsigned char numParity);
|
||||||
|
|
||||||
|
void NormStopSender(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
void NormSetTransmitRate(NormSessionHandle sessionHandle,
|
||||||
|
double bitsPerSecond);
|
||||||
|
|
||||||
|
void NormSetCongestionControl(NormSessionHandle sessionHandle,
|
||||||
|
bool state);
|
||||||
|
|
||||||
|
void NormSetTransmitRateBounds(NormSessionHandle sessionHandle,
|
||||||
|
double rateMin,
|
||||||
|
double rateMax);
|
||||||
|
|
||||||
|
void NormSetAutoParity(NormSessionHandle sessionHandle,
|
||||||
|
unsigned char autoParity);
|
||||||
|
|
||||||
|
void NormSetGrttEstimate(NormSessionHandle sessionHandle,
|
||||||
|
double grttEstimate);
|
||||||
|
|
||||||
|
bool NormAddAckingNode(NormSessionHandle sessionHandle,
|
||||||
|
NormNodeId nodeId);
|
||||||
|
|
||||||
|
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
||||||
|
NormNodeId nodeId);
|
||||||
|
|
||||||
|
NormObjectHandle NormFileEnqueue(NormSessionHandle sessionHandle,
|
||||||
|
const char* fileName,
|
||||||
|
const char* infoPtr = (const char*)0,
|
||||||
|
unsigned int infoLen = 0);
|
||||||
|
|
||||||
|
bool NormDataEnqueue(const char* dataPtr,
|
||||||
|
unsigned long dataLen,
|
||||||
|
const char* infoPtr = (const char*)0,
|
||||||
|
unsigned int infoLen = 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NormObjectHandle NormStreamOpen(NormSessionHandle sessionHandle,
|
||||||
|
unsigned long bufferSize);
|
||||||
|
|
||||||
|
void NormStreamClose(NormObjectHandle streamHandle);
|
||||||
|
|
||||||
|
unsigned int NormStreamWrite(NormObjectHandle streamHandle,
|
||||||
|
const char* buffer,
|
||||||
|
unsigned int numBytes);
|
||||||
|
|
||||||
|
void NormStreamFlush(NormObjectHandle streamHandle,
|
||||||
|
bool eom = false,
|
||||||
|
NormFlushMode flushMode = NORM_FLUSH_PASSIVE);
|
||||||
|
|
||||||
|
void NormStreamSetAutoFlush(NormObjectHandle streamHandle,
|
||||||
|
NormFlushMode flushMode);
|
||||||
|
|
||||||
|
void NormStreamSetPushEnable(NormObjectHandle streamHandle,
|
||||||
|
bool pushEnable);
|
||||||
|
|
||||||
|
void NormStreamMarkEom(NormObjectHandle streamHandle);
|
||||||
|
|
||||||
|
bool NormSetWatermark(NormSessionHandle sessionHandle,
|
||||||
|
NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
/** NORM Receiver Functions */
|
||||||
|
|
||||||
|
bool NormStartReceiver(NormSessionHandle sessionHandle,
|
||||||
|
unsigned long bufferSpace);
|
||||||
|
|
||||||
|
void NormStopReceiver(NormSessionHandle sessionHandle);
|
||||||
|
|
||||||
|
void NormSetSilentReceiver(NormSessionHandle sessionHandle,
|
||||||
|
bool silent);
|
||||||
|
|
||||||
|
void NormSetDefaultUnicastNack(NormSessionHandle sessionHandle,
|
||||||
|
bool unicastNacks);
|
||||||
|
|
||||||
|
void NormNodeSetUnicastNack(NormNodeHandle remoteSender,
|
||||||
|
bool unicastNacks);
|
||||||
|
|
||||||
|
void NormSetDefaultNackingMode(NormSessionHandle sessionHandle,
|
||||||
|
NormNackingMode nackingMode);
|
||||||
|
|
||||||
|
void NormNodeSetNackingMode(NormNodeHandle nodeHandle,
|
||||||
|
NormNackingMode nackingMode);
|
||||||
|
|
||||||
|
void NormObjectSetNackingMode(NormObjectHandle objectHandle,
|
||||||
|
NormNackingMode nackingMode);
|
||||||
|
|
||||||
|
void NormSetDefaultRepairBoundary(NormSessionHandle sessionHandle,
|
||||||
|
NormRepairBoundary repairBoundary);
|
||||||
|
|
||||||
|
void NormNodeSetRepairBoundary(NormNodeHandle nodeHandle,
|
||||||
|
NormRepairBoundary repairBoundary);
|
||||||
|
|
||||||
|
bool NormStreamRead(NormObjectHandle streamHandle,
|
||||||
|
char* buffer,
|
||||||
|
unsigned int* numBytes);
|
||||||
|
|
||||||
|
bool NormStreamSeekMsgStart(NormObjectHandle streamHandle);
|
||||||
|
|
||||||
|
unsigned long NormStreamGetReadOffset(NormObjectHandle streamHandle);
|
||||||
|
|
||||||
|
|
||||||
|
/** NORM Object Functions */
|
||||||
|
|
||||||
|
NormObjectType NormObjectGetType(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
bool NormObjectHasInfo(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
unsigned short NormObjectGetInfoLength(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
unsigned short NormObjectGetInfo(NormObjectHandle objectHandle,
|
||||||
|
char* buffer,
|
||||||
|
unsigned short bufferLen);
|
||||||
|
|
||||||
|
off_t NormObjectGetSize(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
void NormObjectCancel(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
void NormObjectRetain(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
void NormObjectRelease(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
bool NormFileGetName(NormObjectHandle fileHandle,
|
||||||
|
char* nameBuffer,
|
||||||
|
unsigned int bufferLen);
|
||||||
|
|
||||||
|
bool NormFileRename(NormObjectHandle fileHandle,
|
||||||
|
const char* fileName);
|
||||||
|
|
||||||
|
const char*volatile NormDataAccessData(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
char* NormDataDetachData(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
NormNodeHandle NormObjectGetSender(NormObjectHandle objectHandle);
|
||||||
|
|
||||||
|
|
||||||
|
/** NORM Node Functions */
|
||||||
|
|
||||||
|
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
|
void NormNodeRetain(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
|
void NormNodeRelease(NormNodeHandle nodeHandle);
|
||||||
|
|
||||||
|
|
||||||
#endif // _NORM_API
|
#endif // _NORM_API
|
||||||
|
|
|
||||||
|
|
@ -761,7 +761,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
||||||
else if (!strncmp("unicastNacks", cmd, len))
|
else if (!strncmp("unicastNacks", cmd, len))
|
||||||
{
|
{
|
||||||
unicast_nacks = true;
|
unicast_nacks = true;
|
||||||
if (session) session->SetUnicastNacks(true);
|
if (session) session->ClientSetUnicastNacks(true);
|
||||||
}
|
}
|
||||||
else if (!strncmp("silentClient", cmd, len))
|
else if (!strncmp("silentClient", cmd, len))
|
||||||
{
|
{
|
||||||
|
|
@ -1198,8 +1198,8 @@ void NormApp::Notify(NormController::Event event,
|
||||||
} // end switch(object->GetType())
|
} // end switch(object->GetType())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_OBJECT_UPDATE:
|
case RX_OBJECT_UPDATED:
|
||||||
//DMSG(0, "NormApp::Notify(RX_OBJECT_UPDATE) ...\n");
|
//DMSG(0, "NormApp::Notify(RX_OBJECT_UPDATED) ...\n");
|
||||||
switch (object->GetType())
|
switch (object->GetType())
|
||||||
{
|
{
|
||||||
case NormObject::FILE:
|
case NormObject::FILE:
|
||||||
|
|
@ -1212,7 +1212,7 @@ void NormApp::Notify(NormController::Event event,
|
||||||
{
|
{
|
||||||
if (object != rx_stream)
|
if (object != rx_stream)
|
||||||
{
|
{
|
||||||
DMSG(0, "NormApp::Notify(RX_OBJECT_UPDATE) update for invalid stream\n");
|
DMSG(0, "NormApp::Notify(RX_OBJECT_UPDATED) update for invalid stream\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Read the stream when it's updated
|
// Read the stream when it's updated
|
||||||
|
|
@ -1532,7 +1532,7 @@ bool NormApp::OnStartup(int argc, const char*const* argv)
|
||||||
if (output || rx_cache_path)
|
if (output || rx_cache_path)
|
||||||
{
|
{
|
||||||
// StartClient(bufferMax (per-sender))
|
// StartClient(bufferMax (per-sender))
|
||||||
session->SetUnicastNacks(unicast_nacks);
|
session->ClientSetUnicastNacks(unicast_nacks);
|
||||||
session->ClientSetSilent(silent_client);
|
session->ClientSetSilent(silent_client);
|
||||||
if (!session->StartClient(rx_buffer_size, interface_name))
|
if (!session->StartClient(rx_buffer_size, interface_name))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#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
|
||||||
|
#include <sys/types.h> // for off_t
|
||||||
|
|
||||||
#ifdef SIMULATE
|
#ifdef SIMULATE
|
||||||
#define SIM_PAYLOAD_MAX (36+8) // MGEN message size + StreamPayloadHeaderLen()
|
#define SIM_PAYLOAD_MAX (36+8) // MGEN message size + StreamPayloadHeaderLen()
|
||||||
|
|
@ -94,7 +95,9 @@ inline double NormUnquantizeRate(unsigned short rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class is used to describe object "size" and/or "offset"
|
// This class is used to describe object "size" and/or "offset"
|
||||||
// (TBD) This hokey implementation should use "off_t"
|
// (TBD) This hokey implementation should use "off_t" as it's
|
||||||
|
// native storage format and get rid of this custom crap !!!
|
||||||
|
// (We should just get rid of this class !!!!!!!!)
|
||||||
class NormObjectSize
|
class NormObjectSize
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -109,6 +112,7 @@ class NormObjectSize
|
||||||
size >>= 32;
|
size >>= 32;
|
||||||
ASSERT(0 == (size & 0xffff0000));
|
ASSERT(0 == (size & 0xffff0000));
|
||||||
msb = size & 0x0000ffff;
|
msb = size & 0x0000ffff;
|
||||||
|
msb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT16 MSB() const {return msb;}
|
UINT16 MSB() const {return msb;}
|
||||||
|
|
@ -159,6 +163,7 @@ class NormObjectSize
|
||||||
NormObjectSize operator/(const NormObjectSize& b) const;
|
NormObjectSize operator/(const NormObjectSize& b) const;
|
||||||
off_t GetOffset() const
|
off_t GetOffset() const
|
||||||
{
|
{
|
||||||
|
|
||||||
off_t offset = msb;
|
off_t offset = msb;
|
||||||
offset <<= 32;
|
offset <<= 32;
|
||||||
offset += lsb;
|
offset += lsb;
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ NormServerNode::NormServerNode(class NormSession& theSession, NormNodeId nodeId)
|
||||||
|
|
||||||
repair_boundary = session.ClientGetDefaultRepairBoundary();
|
repair_boundary = session.ClientGetDefaultRepairBoundary();
|
||||||
default_nacking_mode = session.ClientGetDefaultNackingMode();
|
default_nacking_mode = session.ClientGetDefaultNackingMode();
|
||||||
unicast_nacks = session.UnicastNacks();
|
unicast_nacks = session.ClientGetUnicastNacks();
|
||||||
// (TBD) get "max_pending_range" value from NormSession parameter
|
// (TBD) get "max_pending_range" value from NormSession parameter
|
||||||
|
|
||||||
repair_timer.SetListener(this, &NormServerNode::OnRepairTimeout);
|
repair_timer.SetListener(this, &NormServerNode::OnRepairTimeout);
|
||||||
|
|
@ -1706,6 +1706,7 @@ void NormServerNode::Activate()
|
||||||
activity_timer.SetInterval(grtt_estimate*NORM_ROBUST_FACTOR);
|
activity_timer.SetInterval(grtt_estimate*NORM_ROBUST_FACTOR);
|
||||||
session.ActivateTimer(activity_timer);
|
session.ActivateTimer(activity_timer);
|
||||||
server_active = false;
|
server_active = false;
|
||||||
|
session.Notify(NormController::REMOTE_SERVER_ACTIVE, this, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1725,7 +1726,7 @@ bool NormServerNode::OnActivityTimeout(ProtoTimer& /*theTimer*/)
|
||||||
DMSG(0, "NormServerNode::OnActivityTimeout() node>%lu server>%lu gone inactive?\n",
|
DMSG(0, "NormServerNode::OnActivityTimeout() node>%lu server>%lu gone inactive?\n",
|
||||||
LocalNodeId(), GetId());
|
LocalNodeId(), GetId());
|
||||||
FreeBuffers();
|
FreeBuffers();
|
||||||
// (TBD) Notify application
|
session.Notify(NormController::REMOTE_SERVER_INACTIVE, this, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ class NormNode
|
||||||
public:
|
public:
|
||||||
NormNode(class NormSession& theSession, NormNodeId nodeId);
|
NormNode(class NormSession& theSession, NormNodeId nodeId);
|
||||||
virtual ~NormNode();
|
virtual ~NormNode();
|
||||||
|
|
||||||
|
NormSession& GetSession() const {return session;}
|
||||||
void Retain();
|
void Retain();
|
||||||
void Release();
|
void Release();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ NormObject::NormObject(NormObject::Type theType,
|
||||||
transport_id(transportId), segment_size(0), pending_info(false), repair_info(false),
|
transport_id(transportId), segment_size(0), pending_info(false), repair_info(false),
|
||||||
current_block_id(0), next_segment_id(0),
|
current_block_id(0), next_segment_id(0),
|
||||||
max_pending_block(0), max_pending_segment(0),
|
max_pending_block(0), max_pending_segment(0),
|
||||||
info(NULL), info_len(0), accepted(false), notify_on_update(true)
|
info_ptr(NULL), info_len(0), accepted(false), notify_on_update(true)
|
||||||
{
|
{
|
||||||
if (theServer)
|
if (theServer)
|
||||||
nacking_mode = theServer->GetDefaultNackingMode();
|
nacking_mode = theServer->GetDefaultNackingMode();
|
||||||
|
|
@ -22,10 +22,10 @@ NormObject::NormObject(NormObject::Type theType,
|
||||||
NormObject::~NormObject()
|
NormObject::~NormObject()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
if (info)
|
if (info_ptr)
|
||||||
{
|
{
|
||||||
delete info;
|
delete info_ptr;
|
||||||
info = NULL;
|
info_ptr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ bool NormObject::Open(const NormObjectSize& objectSize,
|
||||||
{
|
{
|
||||||
pending_info = true;
|
pending_info = true;
|
||||||
info_len = 0;
|
info_len = 0;
|
||||||
if (!(info = new char[segmentSize]))
|
if (!(info_ptr = new char[segmentSize]))
|
||||||
{
|
{
|
||||||
DMSG(0, "NormObject::Open() info allocation error\n");
|
DMSG(0, "NormObject::Open() info allocation error\n");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -84,20 +84,20 @@ bool NormObject::Open(const NormObjectSize& objectSize,
|
||||||
{
|
{
|
||||||
if (infoPtr)
|
if (infoPtr)
|
||||||
{
|
{
|
||||||
if (info) delete []info;
|
if (info_ptr) delete []info_ptr;
|
||||||
if (infoLen > segmentSize)
|
if (infoLen > segmentSize)
|
||||||
{
|
{
|
||||||
DMSG(0, "NormObject::Open() info too big error\n");
|
DMSG(0, "NormObject::Open() info too big error\n");
|
||||||
info_len = 0;
|
info_len = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(info = new char[infoLen]))
|
if (!(info_ptr = new char[infoLen]))
|
||||||
{
|
{
|
||||||
DMSG(0, "NormObject::Open() info allocation error\n");
|
DMSG(0, "NormObject::Open() info allocation error\n");
|
||||||
info_len = 0;
|
info_len = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(info, infoPtr, infoLen);
|
memcpy(info_ptr, infoPtr, infoLen);
|
||||||
info_len = infoLen;
|
info_len = infoLen;
|
||||||
pending_info = true;
|
pending_info = true;
|
||||||
}
|
}
|
||||||
|
|
@ -207,7 +207,7 @@ void NormObject::Close()
|
||||||
bool NormObject::HandleInfoRequest()
|
bool NormObject::HandleInfoRequest()
|
||||||
{
|
{
|
||||||
bool increasedRepair = false;
|
bool increasedRepair = false;
|
||||||
if (info)
|
if (info_ptr)
|
||||||
{
|
{
|
||||||
if (!repair_info)
|
if (!repair_info)
|
||||||
{
|
{
|
||||||
|
|
@ -1047,7 +1047,7 @@ void NormObject::HandleObjectMessage(const NormObjectMsg& msg,
|
||||||
"Warning! info too long.\n", LocalNodeId(), server->GetId(),
|
"Warning! info too long.\n", LocalNodeId(), server->GetId(),
|
||||||
(UINT16)transport_id);
|
(UINT16)transport_id);
|
||||||
}
|
}
|
||||||
memcpy(info, infoMsg.GetInfo(), info_len);
|
memcpy(info_ptr, infoMsg.GetInfo(), info_len);
|
||||||
pending_info = false;
|
pending_info = false;
|
||||||
session.Notify(NormController::RX_OBJECT_INFO, server, this);
|
session.Notify(NormController::RX_OBJECT_INFO, server, this);
|
||||||
}
|
}
|
||||||
|
|
@ -1219,9 +1219,10 @@ void NormObject::HandleObjectMessage(const NormObjectMsg& msg,
|
||||||
block->SetPending(nextSegment);
|
block->SetPending(nextSegment);
|
||||||
block->IncrementErasureCount();
|
block->IncrementErasureCount();
|
||||||
// Clear any erasure/retrieval segments
|
// Clear any erasure/retrieval segments
|
||||||
for (UINT16 i = 0; i < erasureCount; i++)
|
UINT16 i;
|
||||||
|
for (i = 0; i < erasureCount; i++)
|
||||||
block->DetachSegment(server->GetErasureLoc(i));
|
block->DetachSegment(server->GetErasureLoc(i));
|
||||||
for (UINT16 i = 0; i < retrievalCount; i++)
|
for (i = 0; i < retrievalCount; i++)
|
||||||
block->DetachSegment(server->GetRetrievalLoc(i));
|
block->DetachSegment(server->GetRetrievalLoc(i));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1272,7 +1273,7 @@ void NormObject::HandleObjectMessage(const NormObjectMsg& msg,
|
||||||
if (objectUpdated && notify_on_update)
|
if (objectUpdated && notify_on_update)
|
||||||
{
|
{
|
||||||
notify_on_update = false;
|
notify_on_update = false;
|
||||||
session.Notify(NormController::RX_OBJECT_UPDATE, server, this);
|
session.Notify(NormController::RX_OBJECT_UPDATED, server, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1418,7 +1419,7 @@ bool NormObject::NextServerMsg(NormObjectMsg* msg)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (info) msg->SetFlag(NormObjectMsg::FLAG_INFO);
|
if (info_ptr) msg->SetFlag(NormObjectMsg::FLAG_INFO);
|
||||||
msg->SetFecId(129);
|
msg->SetFecId(129);
|
||||||
msg->SetObjectId(transport_id);
|
msg->SetObjectId(transport_id);
|
||||||
|
|
||||||
|
|
@ -1435,7 +1436,7 @@ bool NormObject::NextServerMsg(NormObjectMsg* msg)
|
||||||
{
|
{
|
||||||
// (TBD) set REPAIR_FLAG for retransmitted info
|
// (TBD) set REPAIR_FLAG for retransmitted info
|
||||||
NormInfoMsg* infoMsg = (NormInfoMsg*)msg;
|
NormInfoMsg* infoMsg = (NormInfoMsg*)msg;
|
||||||
infoMsg->SetInfo(info, info_len);
|
infoMsg->SetInfo(info_ptr, info_len);
|
||||||
pending_info = false;
|
pending_info = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1938,7 +1939,7 @@ NormDataObject::NormDataObject(class NormSession& theSession,
|
||||||
const NormObjectId& objectId)
|
const NormObjectId& objectId)
|
||||||
: NormObject(DATA, theSession, theServer, objectId),
|
: NormObject(DATA, theSession, theServer, objectId),
|
||||||
large_block_length(0,0), small_block_length(0,0),
|
large_block_length(0,0), small_block_length(0,0),
|
||||||
data_ptr(NULL), data_max(0)
|
data_ptr(NULL), data_max(0), data_released(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1946,11 +1947,21 @@ NormDataObject::NormDataObject(class NormSession& theSession,
|
||||||
NormDataObject::~NormDataObject()
|
NormDataObject::~NormDataObject()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
if (data_released)
|
||||||
|
{
|
||||||
|
if (data_ptr)
|
||||||
|
{
|
||||||
|
delete data_ptr;
|
||||||
|
data_ptr = NULL;
|
||||||
|
}
|
||||||
|
data_released = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign data object to data ptr
|
// Assign data object to data ptr
|
||||||
bool NormDataObject::Open(char* dataPtr,
|
bool NormDataObject::Open(char* dataPtr,
|
||||||
UINT32 dataLen,
|
UINT32 dataLen,
|
||||||
|
bool dataRelease,
|
||||||
const char* infoPtr,
|
const char* infoPtr,
|
||||||
UINT16 infoLen)
|
UINT16 infoLen)
|
||||||
{
|
{
|
||||||
|
|
@ -1976,15 +1987,16 @@ bool NormDataObject::Open(char* dataPtr,
|
||||||
}
|
}
|
||||||
data_ptr = dataPtr;
|
data_ptr = dataPtr;
|
||||||
data_max = dataLen;
|
data_max = dataLen;
|
||||||
|
data_released = dataRelease;
|
||||||
large_block_length = NormObjectSize(large_block_size) * segment_size;
|
large_block_length = NormObjectSize(large_block_size) * segment_size;
|
||||||
small_block_length = NormObjectSize(small_block_size) * segment_size;
|
small_block_length = NormObjectSize(small_block_size) * segment_size;
|
||||||
return true;
|
return true;
|
||||||
} // end NormDataObject::Open()
|
} // end NormDataObject::Open()
|
||||||
|
|
||||||
bool NormDataObject::Accept(char* dataPtr, UINT32 dataMax)
|
bool NormDataObject::Accept(char* dataPtr, UINT32 dataMax, bool dataRelease)
|
||||||
{
|
{
|
||||||
ASSERT(NULL == server);
|
ASSERT(NULL == server);
|
||||||
if (Open(dataPtr, dataMax))
|
if (Open(dataPtr, dataMax, dataRelease))
|
||||||
{
|
{
|
||||||
NormObject::Accept();
|
NormObject::Accept();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2005,6 +2017,11 @@ bool NormDataObject::WriteSegment(NormBlockId blockId,
|
||||||
const char* buffer,
|
const char* buffer,
|
||||||
bool /*msgStart*/)
|
bool /*msgStart*/)
|
||||||
{
|
{
|
||||||
|
if (NULL == data_ptr)
|
||||||
|
{
|
||||||
|
DMSG(0, "NormDataObject::WriteSegment() error: NULL data_ptr\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
UINT16 len;
|
UINT16 len;
|
||||||
if (blockId == final_block_id)
|
if (blockId == final_block_id)
|
||||||
{
|
{
|
||||||
|
|
@ -2046,6 +2063,11 @@ UINT16 NormDataObject::ReadSegment(NormBlockId blockId,
|
||||||
char* buffer,
|
char* buffer,
|
||||||
bool* /*msgStart*/)
|
bool* /*msgStart*/)
|
||||||
{
|
{
|
||||||
|
if (NULL == data_ptr)
|
||||||
|
{
|
||||||
|
DMSG(0, "NormDataObject::ReadSegment() error: NULL data_ptr\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// Determine segment length from blockId::segmentId
|
// Determine segment length from blockId::segmentId
|
||||||
UINT16 len;
|
UINT16 len;
|
||||||
if (blockId == final_block_id)
|
if (blockId == final_block_id)
|
||||||
|
|
@ -2075,14 +2097,23 @@ UINT16 NormDataObject::ReadSegment(NormBlockId blockId,
|
||||||
segmentSize*segmentId;
|
segmentSize*segmentId;
|
||||||
}
|
}
|
||||||
ASSERT(0 == segmentOffset.MSB());
|
ASSERT(0 == segmentOffset.MSB());
|
||||||
ASSERT(data_max >= (segmentOffset.LSB() + len));
|
if (data_max <= segmentOffset.LSB())
|
||||||
|
return 0;
|
||||||
|
else if (data_max <= (segmentOffset.LSB() + len))
|
||||||
|
len -= (segmentOffset.LSB() + len - data_max);
|
||||||
|
|
||||||
memcpy(buffer, data_ptr + segmentOffset.LSB(), len);
|
memcpy(buffer, data_ptr + segmentOffset.LSB(), len);
|
||||||
return true;
|
return len;
|
||||||
} // end NormDataObject::ReadSegment()
|
} // end NormDataObject::ReadSegment()
|
||||||
|
|
||||||
char* NormDataObject::RetrieveSegment(NormBlockId blockId,
|
char* NormDataObject::RetrieveSegment(NormBlockId blockId,
|
||||||
NormSegmentId segmentId)
|
NormSegmentId segmentId)
|
||||||
{
|
{
|
||||||
|
if (NULL == data_ptr)
|
||||||
|
{
|
||||||
|
DMSG(0, "NormDataObject::RetrieveSegment() error: NULL data_ptr\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
// Determine segment length from blockId::segmentId
|
// Determine segment length from blockId::segmentId
|
||||||
UINT16 len;
|
UINT16 len;
|
||||||
if (blockId == final_block_id)
|
if (blockId == final_block_id)
|
||||||
|
|
@ -2101,7 +2132,7 @@ char* NormDataObject::RetrieveSegment(NormBlockId blockId,
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
char* segment = server->GetRetrievalSegment();
|
char* segment = server->GetRetrievalSegment();
|
||||||
ReadSegment(blockId, segmentId, segment);
|
len = ReadSegment(blockId, segmentId, segment);
|
||||||
memset(segment+len, 0, segment_size-len);
|
memset(segment+len, 0, segment_size-len);
|
||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
|
|
@ -2490,7 +2521,7 @@ bool NormStreamObject::WriteSegment(NormBlockId blockId,
|
||||||
block->GetFirstPending(read_index.segment);
|
block->GetFirstPending(read_index.segment);
|
||||||
NormBlock* tempBlock = block;
|
NormBlock* tempBlock = block;
|
||||||
UINT32 tempOffset = read_offset;
|
UINT32 tempOffset = read_offset;
|
||||||
session.Notify(NormController::RX_OBJECT_UPDATE, server, this);
|
session.Notify(NormController::RX_OBJECT_UPDATED, server, this);
|
||||||
block = stream_buffer.Find(stream_buffer.RangeLo());
|
block = stream_buffer.Find(stream_buffer.RangeLo());
|
||||||
if (tempBlock == block)
|
if (tempBlock == block)
|
||||||
{
|
{
|
||||||
|
|
@ -2954,6 +2985,18 @@ NormSimObject::~NormSimObject()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NormSimObject::Open(UINT32 objectSize,
|
||||||
|
const char* infoPtr ,
|
||||||
|
UINT16 infoLen)
|
||||||
|
{
|
||||||
|
return (server ?
|
||||||
|
true :
|
||||||
|
NormObject::Open(objectSize, infoPtr, infoLen,
|
||||||
|
session.ServerSegmentSize(),
|
||||||
|
session.ServerBlockSize(),
|
||||||
|
session.ServerNumParity()));
|
||||||
|
} // end NormSimObject::Open()
|
||||||
|
|
||||||
UINT16 NormSimObject::ReadSegment(NormBlockId blockId,
|
UINT16 NormSimObject::ReadSegment(NormBlockId blockId,
|
||||||
NormSegmentId segmentId,
|
NormSegmentId segmentId,
|
||||||
char* buffer,
|
char* buffer,
|
||||||
|
|
@ -2975,6 +3018,12 @@ UINT16 NormSimObject::ReadSegment(NormBlockId blockId,
|
||||||
return len;
|
return len;
|
||||||
} // end NormSimObject::ReadSegment()
|
} // end NormSimObject::ReadSegment()
|
||||||
|
|
||||||
|
char* NormSimObject::RetrieveSegment(NormBlockId blockId,
|
||||||
|
NormSegmentId segmentId)
|
||||||
|
{
|
||||||
|
return server ? server->GetRetrievalSegment() : NULL;
|
||||||
|
} // end NormSimObject::RetrieveSegment()
|
||||||
|
|
||||||
#endif // SIMULATE
|
#endif // SIMULATE
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ class NormObject
|
||||||
const NormObjectId& GetId() const {return transport_id;}
|
const NormObjectId& GetId() const {return transport_id;}
|
||||||
const NormObjectSize& GetSize() const {return object_size;}
|
const NormObjectSize& GetSize() const {return object_size;}
|
||||||
bool HaveInfo() const {return (info_len > 0);}
|
bool HaveInfo() const {return (info_len > 0);}
|
||||||
const char* GetInfo() const {return info;}
|
bool HasInfo() const {return (NULL != info_ptr);}
|
||||||
|
|
||||||
|
const char* GetInfo() const {return info_ptr;}
|
||||||
UINT16 GetInfoLength() const {return info_len;}
|
UINT16 GetInfoLength() const {return info_len;}
|
||||||
bool IsStream() const {return (STREAM == type);}
|
bool IsStream() const {return (STREAM == type);}
|
||||||
|
|
||||||
|
|
@ -257,7 +259,7 @@ class NormObject
|
||||||
NormBlockId final_block_id;
|
NormBlockId final_block_id;
|
||||||
UINT16 final_segment_size;
|
UINT16 final_segment_size;
|
||||||
NackingMode nacking_mode;
|
NackingMode nacking_mode;
|
||||||
char* info;
|
char* info_ptr;
|
||||||
UINT16 info_len;
|
UINT16 info_len;
|
||||||
|
|
||||||
// Here are some members used to let us know
|
// Here are some members used to let us know
|
||||||
|
|
@ -321,12 +323,19 @@ class NormDataObject : public NormObject
|
||||||
|
|
||||||
bool Open(char* dataPtr,
|
bool Open(char* dataPtr,
|
||||||
UINT32 dataLen,
|
UINT32 dataLen,
|
||||||
|
bool dataRelease,
|
||||||
const char* infoPtr = NULL,
|
const char* infoPtr = NULL,
|
||||||
UINT16 infoLen = 0);
|
UINT16 infoLen = 0);
|
||||||
bool Accept(char* dataPtr, UINT32 dataMax);
|
bool Accept(char* dataPtr, UINT32 dataMax, bool dataRelease);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
const char* GetData() {return data_ptr;}
|
const char* GetData() {return data_ptr;}
|
||||||
|
char* DetachData()
|
||||||
|
{
|
||||||
|
char* dataPtr = data_ptr;
|
||||||
|
data_ptr = NULL;
|
||||||
|
return dataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool WriteSegment(NormBlockId blockId,
|
virtual bool WriteSegment(NormBlockId blockId,
|
||||||
NormSegmentId segmentId,
|
NormSegmentId segmentId,
|
||||||
|
|
@ -346,6 +355,8 @@ class NormDataObject : public NormObject
|
||||||
NormObjectSize small_block_length;
|
NormObjectSize small_block_length;
|
||||||
char* data_ptr;
|
char* data_ptr;
|
||||||
UINT32 data_max;
|
UINT32 data_max;
|
||||||
|
bool data_released; // when true, data_ptr is deleted
|
||||||
|
// on NormDataObject destruction
|
||||||
}; // end class NormDataObject
|
}; // end class NormDataObject
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -357,7 +368,7 @@ class NormStreamObject : public NormObject
|
||||||
const NormObjectId& objectId);
|
const NormObjectId& objectId);
|
||||||
~NormStreamObject();
|
~NormStreamObject();
|
||||||
|
|
||||||
bool Open(UINT32 bufferSize,
|
bool Open(UINT32 bufferSize,
|
||||||
const char* infoPtr = NULL,
|
const char* infoPtr = NULL,
|
||||||
UINT16 infoLen = 0);
|
UINT16 infoLen = 0);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
@ -477,12 +488,9 @@ class NormSimObject : public NormObject
|
||||||
const NormObjectId& objectId);
|
const NormObjectId& objectId);
|
||||||
~NormSimObject();
|
~NormSimObject();
|
||||||
|
|
||||||
bool Open(UINT32 objectSize,
|
bool Open(UINT32 objectSize,
|
||||||
const char* infoPtr = NULL,
|
const char* infoPtr = NULL,
|
||||||
UINT16 infoLen = 0)
|
UINT16 infoLen = 0);
|
||||||
{
|
|
||||||
return server ? true : NormObject::Open(objectSize, infoPtr, infoLen);
|
|
||||||
}
|
|
||||||
bool Accept() {NormObject::Accept(); return true;}
|
bool Accept() {NormObject::Accept(); return true;}
|
||||||
void Close() {NormObject::Close();}
|
void Close() {NormObject::Close();}
|
||||||
|
|
||||||
|
|
@ -497,10 +505,7 @@ class NormSimObject : public NormObject
|
||||||
bool* msgStart = NULL);
|
bool* msgStart = NULL);
|
||||||
|
|
||||||
virtual char* RetrieveSegment(NormBlockId blockId,
|
virtual char* RetrieveSegment(NormBlockId blockId,
|
||||||
NormSegmentId segmentId)
|
NormSegmentId segmentId);
|
||||||
{
|
|
||||||
return server ? server->GetRetrievalSegment() : NULL;
|
|
||||||
}
|
|
||||||
}; // end class NormSimObject
|
}; // end class NormSimObject
|
||||||
#endif // SIMULATE
|
#endif // SIMULATE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
|
||||||
tx_socket(ProtoSocket::UDP), rx_socket(ProtoSocket::UDP),
|
tx_socket(ProtoSocket::UDP), rx_socket(ProtoSocket::UDP),
|
||||||
local_node_id(localNodeId),
|
local_node_id(localNodeId),
|
||||||
ttl(DEFAULT_TTL), loopback(false),
|
ttl(DEFAULT_TTL), loopback(false),
|
||||||
tx_rate(DEFAULT_TRANSMIT_RATE/8.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),
|
||||||
ndata(DEFAULT_NDATA), nparity(DEFAULT_NPARITY), auto_parity(0), extra_parity(0),
|
ndata(DEFAULT_NDATA), nparity(DEFAULT_NPARITY), auto_parity(0), extra_parity(0),
|
||||||
next_tx_object_id(0), tx_cache_count_min(8), tx_cache_count_max(256),
|
next_tx_object_id(0), tx_cache_count_min(8), tx_cache_count_max(256),
|
||||||
|
|
@ -112,12 +112,6 @@ bool NormSession::Open(const char* interfaceName)
|
||||||
|
|
||||||
if (address.IsMulticast())
|
if (address.IsMulticast())
|
||||||
{
|
{
|
||||||
if (!rx_socket.JoinGroup(address, interfaceName))
|
|
||||||
{
|
|
||||||
DMSG(0, "NormSession::Open() rx_socket join group error\n");
|
|
||||||
Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
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");
|
||||||
|
|
@ -132,11 +126,27 @@ bool NormSession::Open(const char* interfaceName)
|
||||||
}
|
}
|
||||||
if (interfaceName)
|
if (interfaceName)
|
||||||
{
|
{
|
||||||
rx_socket.SetMulticastInterface(interfaceName);
|
|
||||||
tx_socket.SetMulticastInterface(interfaceName);
|
|
||||||
strncpy(interface_name, interfaceName, 31);
|
strncpy(interface_name, interfaceName, 31);
|
||||||
interface_name[31] = '\0';
|
interface_name[31] = '\0';
|
||||||
}
|
}
|
||||||
|
if ('\0' != interface_name[0])
|
||||||
|
{
|
||||||
|
bool result = rx_socket.SetMulticastInterface(interface_name);
|
||||||
|
result &= tx_socket.SetMulticastInterface(interface_name);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
DMSG(0, "NormSession::Open() error setting multicast interface\n");
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
interfaceName = interface_name;
|
||||||
|
}
|
||||||
|
if (!rx_socket.JoinGroup(address, interfaceName))
|
||||||
|
{
|
||||||
|
DMSG(0, "NormSession::Open() rx_socket join group error\n");
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < DEFAULT_MESSAGE_POOL_DEPTH; i++)
|
for (unsigned int i = 0; i < DEFAULT_MESSAGE_POOL_DEPTH; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -179,6 +189,24 @@ void NormSession::Close()
|
||||||
} // end NormSession::Close()
|
} // end NormSession::Close()
|
||||||
|
|
||||||
|
|
||||||
|
bool NormSession::SetMulticastInterface(const char* interfaceName)
|
||||||
|
{
|
||||||
|
if (interfaceName)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
if (rx_socket.IsOpen())
|
||||||
|
result &= rx_socket.SetMulticastInterface(interfaceName);
|
||||||
|
if (tx_socket.IsOpen())
|
||||||
|
result &= tx_socket.SetMulticastInterface(interfaceName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
interface_name[0] = '\0';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // end NormSession::SetMulticastInterface()
|
||||||
|
|
||||||
void NormSession::SetTxRate(double txRate)
|
void NormSession::SetTxRate(double txRate)
|
||||||
{
|
{
|
||||||
txRate /= 8.0; // convert to bytes/sec
|
txRate /= 8.0; // convert to bytes/sec
|
||||||
|
|
@ -193,7 +221,7 @@ void NormSession::SetTxRate(double txRate)
|
||||||
}
|
}
|
||||||
tx_rate = txRate;
|
tx_rate = txRate;
|
||||||
}
|
}
|
||||||
else if (0.0 == tx_rate)
|
else if ((0.0 == tx_rate) && IsOpen())
|
||||||
{
|
{
|
||||||
tx_rate = txRate;
|
tx_rate = txRate;
|
||||||
tx_timer.SetInterval(0.0);
|
tx_timer.SetInterval(0.0);
|
||||||
|
|
@ -205,6 +233,37 @@ void NormSession::SetTxRate(double txRate)
|
||||||
}
|
}
|
||||||
} // end NormSession::SetTxRate()
|
} // end NormSession::SetTxRate()
|
||||||
|
|
||||||
|
void NormSession::SetTxRateBounds(double rateMin, double rateMax)
|
||||||
|
{
|
||||||
|
// Make sure min <= max
|
||||||
|
if ((rateMin >= 0.0) && (rateMax >= 0.0))
|
||||||
|
{
|
||||||
|
if (rateMin > rateMax)
|
||||||
|
{
|
||||||
|
double temp = rateMin;
|
||||||
|
rateMin = rateMax;
|
||||||
|
rateMax = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rateMin < 0.0)
|
||||||
|
tx_rate_min = -1.0;
|
||||||
|
else
|
||||||
|
tx_rate_min = rateMin/8.0; // convert to bytes/second
|
||||||
|
if (rateMax < 0.0)
|
||||||
|
tx_rate_max = -1.0;
|
||||||
|
else
|
||||||
|
tx_rate_max = rateMax/8.0; // convert to bytes/second
|
||||||
|
if (cc_enable)
|
||||||
|
{
|
||||||
|
if ((tx_rate_min >= 0.0) && (tx_rate < tx_rate_min))
|
||||||
|
tx_rate = tx_rate_min;
|
||||||
|
if ((tx_rate_max >= 0.0) && (tx_rate > tx_rate_max))
|
||||||
|
tx_rate = tx_rate_max;
|
||||||
|
SetTxRate(tx_rate*8.0);
|
||||||
|
}
|
||||||
|
} // end NormSession::SetTxRateBounds()
|
||||||
|
|
||||||
|
|
||||||
bool NormSession::StartServer(UINT32 bufferSpace,
|
bool NormSession::StartServer(UINT32 bufferSpace,
|
||||||
UINT16 segmentSize,
|
UINT16 segmentSize,
|
||||||
UINT16 numData,
|
UINT16 numData,
|
||||||
|
|
@ -285,7 +344,15 @@ bool NormSession::StartServer(UINT32 bufferSpace,
|
||||||
//probe_timer.SetInterval(0.0);
|
//probe_timer.SetInterval(0.0);
|
||||||
probe_pending = probe_reset = false;
|
probe_pending = probe_reset = false;
|
||||||
|
|
||||||
if (cc_enable) tx_rate = segmentSize;
|
if (cc_enable)
|
||||||
|
{
|
||||||
|
tx_rate = segmentSize;
|
||||||
|
if ((tx_rate_min >= 0.0) && (tx_rate < tx_rate_min))
|
||||||
|
tx_rate = tx_rate_min;
|
||||||
|
if ((tx_rate_max >= 0.0) && (tx_rate > tx_rate_max))
|
||||||
|
tx_rate = tx_rate_max;
|
||||||
|
}
|
||||||
|
|
||||||
OnProbeTimeout(probe_timer);
|
OnProbeTimeout(probe_timer);
|
||||||
ActivateTimer(probe_timer);
|
ActivateTimer(probe_timer);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -782,7 +849,7 @@ NormDataObject* NormSession::QueueTxData(const char* dataPtr,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!obj->Open((char*)dataPtr, dataLen, infoPtr, infoLen))
|
if (!obj->Open((char*)dataPtr, dataLen, false, infoPtr, infoLen))
|
||||||
{
|
{
|
||||||
DMSG(0, "NormSession::QueueTxData() object open error\n");
|
DMSG(0, "NormSession::QueueTxData() object open error\n");
|
||||||
delete obj;
|
delete obj;
|
||||||
|
|
@ -1263,6 +1330,7 @@ void NormSession::ClientHandleObjectMessage(const struct timeval& currentTime,
|
||||||
{
|
{
|
||||||
if ((theServer = new NormServerNode(*this, msg.GetSourceId())))
|
if ((theServer = new NormServerNode(*this, msg.GetSourceId())))
|
||||||
{
|
{
|
||||||
|
Notify(NormController::REMOTE_SERVER_NEW, theServer, NULL);
|
||||||
if (theServer->Open(msg.GetSessionId()))
|
if (theServer->Open(msg.GetSessionId()))
|
||||||
{
|
{
|
||||||
server_tree.AttachNode(theServer);
|
server_tree.AttachNode(theServer);
|
||||||
|
|
@ -2821,10 +2889,18 @@ void NormSession::AdjustRate(bool onResponse)
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't let tx_rate below MIN(one segment per grtt, one segment per second)
|
||||||
double minRate = ((double)segment_size) / grtt_measured;
|
double minRate = ((double)segment_size) / grtt_measured;
|
||||||
minRate = MIN((double)segment_size, minRate);
|
minRate = MIN((double)segment_size, minRate);
|
||||||
tx_rate = MAX(tx_rate, minRate);
|
tx_rate = MAX(tx_rate, minRate);
|
||||||
|
|
||||||
|
// Keep "tx_rate" within user set rate bounds (if any)
|
||||||
|
if ((tx_rate_min >= 0.0) && (tx_rate < tx_rate_min))
|
||||||
|
tx_rate = tx_rate_min;
|
||||||
|
if ((tx_rate_max >= 0.0) && (tx_rate > tx_rate_max))
|
||||||
|
tx_rate = tx_rate_max;
|
||||||
|
|
||||||
struct timeval currentTime;
|
struct timeval currentTime;
|
||||||
::ProtoSystemTime(currentTime);
|
::ProtoSystemTime(currentTime);
|
||||||
double theTime = (double)currentTime.tv_sec + 1.0e-06 * ((double)currentTime.tv_usec);
|
double theTime = (double)currentTime.tv_sec + 1.0e-06 * ((double)currentTime.tv_usec);
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@ class NormController
|
||||||
TX_OBJECT_PURGED,
|
TX_OBJECT_PURGED,
|
||||||
LOCAL_SERVER_CLOSED,
|
LOCAL_SERVER_CLOSED,
|
||||||
REMOTE_SERVER_NEW,
|
REMOTE_SERVER_NEW,
|
||||||
REMOTE_SERVER_INACTIVE,
|
|
||||||
REMOTE_SERVER_ACTIVE,
|
REMOTE_SERVER_ACTIVE,
|
||||||
|
REMOTE_SERVER_INACTIVE,
|
||||||
|
REMOTE_SERVER_PURGED,
|
||||||
RX_OBJECT_NEW,
|
RX_OBJECT_NEW,
|
||||||
RX_OBJECT_INFO,
|
RX_OBJECT_INFO,
|
||||||
RX_OBJECT_UPDATE,
|
RX_OBJECT_UPDATED,
|
||||||
RX_OBJECT_COMPLETED,
|
RX_OBJECT_COMPLETED,
|
||||||
RX_OBJECT_ABORTED
|
RX_OBJECT_ABORTED
|
||||||
};
|
};
|
||||||
|
|
@ -102,6 +103,7 @@ class NormSession
|
||||||
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 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;
|
||||||
|
|
@ -129,6 +131,7 @@ class NormSession
|
||||||
void SetBackoffFactor(double value) {backoff_factor = value;}
|
void SetBackoffFactor(double value) {backoff_factor = value;}
|
||||||
bool CongestionControl() {return cc_enable;}
|
bool CongestionControl() {return cc_enable;}
|
||||||
void SetCongestionControl(bool state) {cc_enable = state;}
|
void SetCongestionControl(bool state) {cc_enable = state;}
|
||||||
|
void SetTxRateBounds(double rateMin, double rateMax);
|
||||||
|
|
||||||
void Notify(NormController::Event event,
|
void Notify(NormController::Event event,
|
||||||
class NormServerNode* server,
|
class NormServerNode* server,
|
||||||
|
|
@ -249,8 +252,8 @@ class NormSession
|
||||||
bool IsClient() const {return is_client;}
|
bool IsClient() const {return is_client;}
|
||||||
unsigned long RemoteServerBufferSize() const
|
unsigned long RemoteServerBufferSize() const
|
||||||
{return remote_server_buffer_size;}
|
{return remote_server_buffer_size;}
|
||||||
void SetUnicastNacks(bool state) {unicast_nacks = state;}
|
void ClientSetUnicastNacks(bool state) {unicast_nacks = state;}
|
||||||
bool UnicastNacks() const {return unicast_nacks;}
|
bool ClientGetUnicastNacks() const {return unicast_nacks;}
|
||||||
void ClientSetSilent(bool state) {client_silent = state;}
|
void ClientSetSilent(bool state) {client_silent = state;}
|
||||||
bool ClientIsSilent() const {return client_silent;}
|
bool ClientIsSilent() const {return client_silent;}
|
||||||
|
|
||||||
|
|
@ -342,6 +345,8 @@ class NormSession
|
||||||
bool loopback; // to receive own traffic
|
bool loopback; // to receive own traffic
|
||||||
char interface_name[32];
|
char interface_name[32];
|
||||||
double tx_rate; // bytes per second
|
double tx_rate; // bytes per second
|
||||||
|
double tx_rate_min;
|
||||||
|
double tx_rate_max;
|
||||||
double backoff_factor;
|
double backoff_factor;
|
||||||
|
|
||||||
// Server parameters and state
|
// Server parameters and state
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ NormSimAgent::NormSimAgent(ProtoTimerMgr& timerMgr,
|
||||||
tx_object_size(0), tx_object_interval(0.0),
|
tx_object_size(0), tx_object_interval(0.0),
|
||||||
tx_object_size_min(0), tx_object_size_max(0),
|
tx_object_size_min(0), tx_object_size_max(0),
|
||||||
tx_repeat_count(0), tx_repeat_interval(0.0),
|
tx_repeat_count(0), tx_repeat_interval(0.0),
|
||||||
stream(NULL), auto_stream(false), push_stream(false),
|
stream(NULL), auto_stream(false), push_mode(false),
|
||||||
flush_mode(NormStreamObject::FLUSH_PASSIVE),
|
flush_mode(NormStreamObject::FLUSH_PASSIVE),
|
||||||
mgen(NULL), msg_sync(false), mgen_bytes(0), mgen_pending_bytes(0),
|
mgen(NULL), msg_sync(false), mgen_bytes(0), mgen_pending_bytes(0),
|
||||||
tracing(false), tx_loss(0.0), rx_loss(0.0)
|
tracing(false), tx_loss(0.0), rx_loss(0.0)
|
||||||
|
|
@ -397,6 +397,8 @@ bool NormSimAgent::ProcessCommand(const char* cmd, const char* val)
|
||||||
DMSG(0, "NormSimAgent::ProcessCommand(sendStream) error opening stream!\n");
|
DMSG(0, "NormSimAgent::ProcessCommand(sendStream) error opening stream!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
stream->SetFlushMode(flush_mode);
|
||||||
|
stream->SetPushMode(push_mode);
|
||||||
auto_stream = true;
|
auto_stream = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -430,6 +432,8 @@ bool NormSimAgent::ProcessCommand(const char* cmd, const char* val)
|
||||||
DMSG(0, "NormSimAgent::ProcessCommand(openStream) error opening stream!\n");
|
DMSG(0, "NormSimAgent::ProcessCommand(openStream) error opening stream!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
stream->SetFlushMode(flush_mode);
|
||||||
|
stream->SetPushMode(push_mode);
|
||||||
auto_stream = false;
|
auto_stream = false;
|
||||||
tx_msg_len = tx_msg_index = 0;
|
tx_msg_len = tx_msg_index = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -469,9 +473,9 @@ bool NormSimAgent::ProcessCommand(const char* cmd, const char* val)
|
||||||
else if (!strncmp("push", cmd, len))
|
else if (!strncmp("push", cmd, len))
|
||||||
{
|
{
|
||||||
if (!strcmp(val, "on"))
|
if (!strcmp(val, "on"))
|
||||||
push_stream = true;
|
push_mode = true;
|
||||||
else if (!strcmp(val, "off"))
|
else if (!strcmp(val, "off"))
|
||||||
push_stream = false;
|
push_mode = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DMSG(0, "NormSimAgent::ProcessCommand(push) invalid argument!\n");
|
DMSG(0, "NormSimAgent::ProcessCommand(push) invalid argument!\n");
|
||||||
|
|
@ -592,13 +596,12 @@ void NormSimAgent::OnInputReady()
|
||||||
{
|
{
|
||||||
unsigned int bytesWrote = stream->Write(tx_msg_buffer+tx_msg_index,
|
unsigned int bytesWrote = stream->Write(tx_msg_buffer+tx_msg_index,
|
||||||
tx_msg_len - tx_msg_index,
|
tx_msg_len - tx_msg_index,
|
||||||
NormStreamObject::FLUSH_NONE,
|
false);
|
||||||
false, push_stream);
|
|
||||||
tx_msg_index += bytesWrote;
|
tx_msg_index += bytesWrote;
|
||||||
if (tx_msg_index == tx_msg_len)
|
if (tx_msg_index == tx_msg_len)
|
||||||
{
|
{
|
||||||
// Provide EOM indication to norm stream
|
// Mark EOM _and_ flush (using set flush mode)
|
||||||
stream->Write(NULL, 0, flush_mode, true, false);
|
stream->Write(NULL, 0, true);
|
||||||
tx_msg_index = tx_msg_len = 0;
|
tx_msg_index = tx_msg_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -609,7 +612,7 @@ bool NormSimAgent::FlushStream()
|
||||||
{
|
{
|
||||||
if (stream && session && session->IsServer())
|
if (stream && session && session->IsServer())
|
||||||
{
|
{
|
||||||
stream->Write(NULL, 0, NormStreamObject::FLUSH_ACTIVE, false, false);
|
stream->Flush(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -636,9 +639,7 @@ void NormSimAgent::Notify(NormController::Event event,
|
||||||
// sending a dummy byte stream
|
// sending a dummy byte stream
|
||||||
char buffer[NormMsg::MAX_SIZE];
|
char buffer[NormMsg::MAX_SIZE];
|
||||||
unsigned int count =
|
unsigned int count =
|
||||||
stream->Write(buffer, segment_size,
|
stream->Write(buffer, segment_size, false);
|
||||||
NormStreamObject::FLUSH_NONE,
|
|
||||||
false, false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ class NormSimAgent : public NormController
|
||||||
|
|
||||||
NormStreamObject* stream;
|
NormStreamObject* stream;
|
||||||
bool auto_stream;
|
bool auto_stream;
|
||||||
bool push_stream;
|
bool push_mode;
|
||||||
NormStreamObject::FlushType flush_mode;
|
NormStreamObject::FlushMode flush_mode;
|
||||||
char* tx_msg_buffer;
|
char* tx_msg_buffer;
|
||||||
unsigned int tx_msg_len;
|
unsigned int tx_msg_len;
|
||||||
unsigned int tx_msg_index;
|
unsigned int tx_msg_index;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,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.
|
||||||
NormStreamSetFlushMode(stream, NORM_FLUSH_PASSIVE);
|
NormStreamSetAutoFlush(stream, NORM_FLUSH_PASSIVE);
|
||||||
|
|
||||||
|
|
||||||
// Some variable for stream input/output
|
// Some variable for stream input/output
|
||||||
|
|
@ -143,18 +143,11 @@ int main(int argc, char* argv[])
|
||||||
// Assume info contains '/' delimited <path/fileName> string
|
// Assume info contains '/' delimited <path/fileName> string
|
||||||
if (NORM_OBJECT_FILE == NormObjectGetType(theEvent.object))
|
if (NORM_OBJECT_FILE == NormObjectGetType(theEvent.object))
|
||||||
{
|
{
|
||||||
NormObjectTransportId id = NormObjectGetTransportId(theEvent.object);
|
|
||||||
if (0 != (id & 0x01))
|
|
||||||
{
|
|
||||||
//NormObjectCancel(theEvent.object);
|
|
||||||
//break;
|
|
||||||
}
|
|
||||||
|
|
||||||
char fileName[PATH_MAX];
|
char fileName[PATH_MAX];
|
||||||
strcpy(fileName, cachePath);
|
strcpy(fileName, cachePath);
|
||||||
int pathLen = strlen(fileName);
|
int pathLen = strlen(fileName);
|
||||||
unsigned short nameLen = PATH_MAX - pathLen;
|
unsigned short nameLen = PATH_MAX - pathLen;
|
||||||
NormObjectGetInfo(theEvent.object, fileName+pathLen, &nameLen);
|
nameLen = NormObjectGetInfo(theEvent.object, fileName+pathLen, nameLen);
|
||||||
fileName[nameLen + pathLen] = '\0';
|
fileName[nameLen + pathLen] = '\0';
|
||||||
char* ptr = fileName + 5;
|
char* ptr = fileName + 5;
|
||||||
while ('\0' != *ptr)
|
while ('\0' != *ptr)
|
||||||
|
|
@ -170,7 +163,7 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NORM_RX_OBJECT_UPDATE:
|
case NORM_RX_OBJECT_UPDATED:
|
||||||
{
|
{
|
||||||
//TRACE("normTest: NORM_RX_OBJECT_UPDATE event ...\n");
|
//TRACE("normTest: NORM_RX_OBJECT_UPDATE event ...\n");
|
||||||
if (NORM_OBJECT_STREAM != NormObjectGetType(theEvent.object))
|
if (NORM_OBJECT_STREAM != NormObjectGetType(theEvent.object))
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@
|
||||||
|
|
||||||
#ifndef _NORM_VERSION
|
#ifndef _NORM_VERSION
|
||||||
#define _NORM_VERSION
|
#define _NORM_VERSION
|
||||||
#define VERSION "1.2b4"
|
#define VERSION "1.2b5"
|
||||||
#endif // _NORM_VERSION
|
#endif // _NORM_VERSION
|
||||||
|
|
||||||
|
|
|
||||||
BIN
win32/Norm.opt
BIN
win32/Norm.opt
Binary file not shown.
Loading…
Reference in New Issue