cmRtNet.h/c : The rtSubIdx of the owning cmRtSys sub-system is now set in

cmNetAlloc().  rtSubIdx is no longer required to locate a remote endpoint
because IP/"node label" is enough information to determine the rtSubIdx.
Several changes were made to simplify the interface to cmRtNet based on this
observation.
This commit is contained in:
kpl 2014-06-15 14:36:12 -07:00
parent b6e71997f3
commit 10943e18e3
2 changed files with 62 additions and 38 deletions

View File

@ -30,14 +30,15 @@ typedef struct cmRtNetEnd_str
{ {
cmChar_t* label; cmChar_t* label;
unsigned id; unsigned id;
unsigned rtSubIdx;
struct cmRtNetNode_str* np; // Owner node. struct cmRtNetNode_str* np; // Owner node.
struct cmRtNetEnd_str* link; struct cmRtNetEnd_str* link;
} cmRtNetEnd_t; } cmRtNetEnd_t;
struct cmRtNet_str;
typedef struct cmRtNetNode_str typedef struct cmRtNetNode_str
{ {
unsigned rtSubIdx; // rtSubIdx of the sub-system which owns this node
cmChar_t* label; // Node label. cmChar_t* label; // Node label.
struct sockaddr_in sockaddr; // Socket address struct sockaddr_in sockaddr; // Socket address
cmChar_t* addr; // IP Address (human readable) cmChar_t* addr; // IP Address (human readable)
@ -50,10 +51,11 @@ typedef struct cmRtNetNode_str
struct cmRtNetNode_str* link; struct cmRtNetNode_str* link;
} cmRtNetNode_t; } cmRtNetNode_t;
typedef struct typedef struct cmRtNet_str
{ {
cmErr_t err; // Error state object cmErr_t err; // Error state object
unsigned flags; // See kXXXNetFl above. unsigned flags; // See kXXXNetFl above.
unsigned rtSubIdx; // rtSubIdx of the owning sub-system
cmUdpH_t udpH; // UDP port handle cmUdpH_t udpH; // UDP port handle
cmUdpCallback_t cbFunc; // Client callback to receive incoming messages from network. cmUdpCallback_t cbFunc; // Client callback to receive incoming messages from network.
void* cbArg; // void* cbArg; //
@ -173,7 +175,7 @@ cmRtNetRC_t _cmRtNetReleaseNode( cmRtNet_t* p, cmRtNetNode_t* np )
return cmErrMsg(&p->err,kNodeNotFoundNetRC,"Node to release not found."); return cmErrMsg(&p->err,kNodeNotFoundNetRC,"Node to release not found.");
} }
cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmChar_t* addr, cmUdpPort_t port, const struct sockaddr_in* saddr, unsigned flags, unsigned endPtCnt ) cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, unsigned rtSubIdx, const cmChar_t* addr, cmUdpPort_t port, const struct sockaddr_in* saddr, unsigned flags, unsigned endPtCnt )
{ {
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
cmRtNetNode_t* np; cmRtNetNode_t* np;
@ -190,6 +192,7 @@ cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmCha
if( saddr != NULL ) if( saddr != NULL )
np->sockaddr = *saddr; np->sockaddr = *saddr;
np->rtSubIdx = rtSubIdx;
np->addr = addr==NULL ? NULL : cmMemAllocStr(addr); np->addr = addr==NULL ? NULL : cmMemAllocStr(addr);
np->port = port; np->port = port;
np->flags = flags; np->flags = flags;
@ -200,11 +203,11 @@ cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmCha
return rc; return rc;
} }
cmRtNetEnd_t* _cmRtNetFindNodeEnd(cmRtNetNode_t* np, unsigned rtSubIdx, const cmChar_t* endPtLabel ) cmRtNetEnd_t* _cmRtNetFindNodeEnd(cmRtNetNode_t* np, const cmChar_t* endPtLabel )
{ {
cmRtNetEnd_t* ep = np->ends; cmRtNetEnd_t* ep = np->ends;
for(; ep!=NULL; ep=ep->link) for(; ep!=NULL; ep=ep->link)
if( ep->rtSubIdx==rtSubIdx && strcmp(ep->label,endPtLabel)==0 ) if( strcmp(ep->label,endPtLabel)==0 )
return ep; return ep;
return NULL; return NULL;
} }
@ -223,12 +226,12 @@ cmRtNetEnd_t* _cmRtNetIndexToEndpoint( cmRtNet_t* p, cmRtNetNode_t* np, unsigned
return NULL; return NULL;
} }
cmRtNetRC_t _cmRtNetCreateEndpoint( cmRtNet_t* p, cmRtNetNode_t* np, unsigned rtSubIdx, const cmChar_t* endPtLabel, unsigned endPtId ) cmRtNetRC_t _cmRtNetCreateEndpoint( cmRtNet_t* p, cmRtNetNode_t* np, const cmChar_t* endPtLabel, unsigned endPtId )
{ {
if( endPtLabel == NULL ) if( endPtLabel == NULL )
return cmErrMsg(&p->err,kInvalidLabelNetRC,"A null or blank node label was encountered."); return cmErrMsg(&p->err,kInvalidLabelNetRC,"A null or blank node label was encountered.");
if( _cmRtNetFindNodeEnd( np, rtSubIdx, endPtLabel) != NULL) if( _cmRtNetFindNodeEnd( np, endPtLabel) != NULL)
return cmErrMsg(&p->err,kDuplEndNetRC,"A duplicate endpoint ('%s') was encountered on node '%s'.",endPtLabel,np->label); return cmErrMsg(&p->err,kDuplEndNetRC,"A duplicate endpoint ('%s') was encountered on node '%s'.",endPtLabel,np->label);
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
@ -236,7 +239,6 @@ cmRtNetRC_t _cmRtNetCreateEndpoint( cmRtNet_t* p, cmRtNetNode_t* np, unsigned rt
ep->label = cmMemAllocStr(endPtLabel); ep->label = cmMemAllocStr(endPtLabel);
ep->id = endPtId; ep->id = endPtId;
ep->rtSubIdx = rtSubIdx;
ep->np = np; ep->np = np;
ep->link = np->ends; ep->link = np->ends;
np->ends = ep; np->ends = ep;
@ -386,7 +388,7 @@ const cmChar_t* cmRtNetSyncMsgLabel( const cmRtNetSyncMsg_t* m )
return ""; return "";
} }
cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, cmUdpCallback_t cbFunc, void* cbArg ) cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, unsigned rtSubIdx, cmUdpCallback_t cbFunc, void* cbArg )
{ {
cmRtNetRC_t rc; cmRtNetRC_t rc;
if((rc = cmRtNetFree(hp)) != kOkNetRC ) if((rc = cmRtNetFree(hp)) != kOkNetRC )
@ -402,6 +404,7 @@ cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, cmUdpCallback_t cbFunc,
goto errLabel; goto errLabel;
} }
p->rtSubIdx = rtSubIdx;
p->udpTimeOutMs = 50; p->udpTimeOutMs = 50;
p->udpRecvBufByteCnt = 8192; p->udpRecvBufByteCnt = 8192;
p->cbFunc = cbFunc; p->cbFunc = cbFunc;
@ -478,7 +481,7 @@ cmRtNetRC_t _cmRtNetSendEndpointReplyMsg( cmRtNet_t* p, cmRtNetNode_t* np, cmRt
{ {
msgLabel = ep->label; // ... send next local endpoint msgLabel = ep->label; // ... send next local endpoint
msgId = ep->id; msgId = ep->id;
msgRtSubIdx = ep->rtSubIdx; msgRtSubIdx = ep->np->rtSubIdx;
} }
else // .... all local endpoints have been sent else // .... all local endpoints have been sent
{ {
@ -573,7 +576,7 @@ cmRtNetRC_t _cmRtNetSyncModeRecv( cmRtNet_t* p, const char* data, unsigned data
// create a node proxy to represent the remote node // create a node proxy to represent the remote node
// (Note:m.id == remote node endpoint count (i.e. the count of endpoints expected for the remote node.)) // (Note:m.id == remote node endpoint count (i.e. the count of endpoints expected for the remote node.))
if(( rc = _cmRtNetCreateNode(p,m.label,NULL,0,fromAddr,0,m.id)) != kOkNetRC ) if(( rc = _cmRtNetCreateNode(p,m.label,m.rtSubIdx,NULL,0,fromAddr,0,m.id)) != kOkNetRC )
goto errLabel; goto errLabel;
np = p->nodes; // newest node is always the first node np = p->nodes; // newest node is always the first node
@ -583,7 +586,7 @@ cmRtNetRC_t _cmRtNetSyncModeRecv( cmRtNet_t* p, const char* data, unsigned data
{ {
case kHelloSelNetId: case kHelloSelNetId:
_cmRtNetRpt(p,"rcv hello\n"); // reply with local node _cmRtNetRpt(p,"rcv hello\n"); // reply with local node
rc = _cmRtNetSendSyncMsg( p, np, kNodeSelNetId, p->localNode->label, p->localNode->endPtCnt, cmInvalidIdx ); rc = _cmRtNetSendSyncMsg( p, np, kNodeSelNetId, p->localNode->label, p->localNode->endPtCnt, p->localNode->rtSubIdx );
break; break;
case kNodeSelNetId: case kNodeSelNetId:
@ -615,12 +618,12 @@ cmRtNetRC_t _cmRtNetSyncModeRecv( cmRtNet_t* p, const char* data, unsigned data
} }
// attempt to find the end point // attempt to find the end point
if((ep = _cmRtNetFindNodeEnd(np, m.rtSubIdx, m.label)) != NULL ) if((ep = _cmRtNetFindNodeEnd(np, m.label)) != NULL )
ep->id = m.id; // the endpoint was found update the endPtId ep->id = m.id; // the endpoint was found update the endPtId
else else
{ {
// create a local proxy for the endpoint // create a local proxy for the endpoint
if((rc = _cmRtNetCreateEndpoint(p,np,m.rtSubIdx,m.label,m.id)) != kOkNetRC ) if((rc = _cmRtNetCreateEndpoint(p,np,m.label,m.id)) != kOkNetRC )
goto errLabel; goto errLabel;
} }
@ -675,7 +678,7 @@ cmRtNetRC_t cmRtNetInitialize( cmRtNetH_t h, const cmChar_t* bcastAddr, const cm
} }
// create the local node // create the local node
if((rc = _cmRtNetCreateNode(p,nodeLabel, ipAddr, port, NULL, kLocalNodeNetFl, 0)) != kOkNetRC ) if((rc = _cmRtNetCreateNode(p,nodeLabel, p->rtSubIdx, ipAddr, port, NULL, kLocalNodeNetFl, 0)) != kOkNetRC )
goto errLabel; goto errLabel;
// the last created node is always the first node on the list // the last created node is always the first node on the list
@ -705,7 +708,7 @@ bool cmRtNetIsInitialized( cmRtNetH_t h )
} }
cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, unsigned rtSubIdx, const cmChar_t* endPtLabel, unsigned endPtId ) cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, const cmChar_t* endPtLabel, unsigned endPtId )
{ {
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
cmRtNet_t* p = _cmRtNetHandleToPtr(h); cmRtNet_t* p = _cmRtNetHandleToPtr(h);
@ -713,7 +716,7 @@ cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, unsigned rtSubIdx, const cmCh
if( p->localNode == NULL ) if( p->localNode == NULL )
return cmErrMsg(&p->err,kLocalNodeNetRC,"Local endpoints may not be added if a local node has not been defined."); return cmErrMsg(&p->err,kLocalNodeNetRC,"Local endpoints may not be added if a local node has not been defined.");
if((rc = _cmRtNetCreateEndpoint(p, p->localNode,rtSubIdx,endPtLabel,endPtId )) == kOkNetRC ) if((rc = _cmRtNetCreateEndpoint(p, p->localNode,endPtLabel,endPtId )) == kOkNetRC )
p->localNode->endPtCnt += 1; p->localNode->endPtCnt += 1;
return rc; return rc;
@ -750,7 +753,7 @@ cmRtNetRC_t cmRtNetReceive( cmRtNetH_t h )
return rc; return rc;
} }
cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, unsigned rtSubIdx, const cmChar_t* endptLabel, cmRtNetEndptH_t* hp ) cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, cmRtNetEndptH_t* hp )
{ {
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
cmRtNet_t* p = _cmRtNetHandleToPtr(h); cmRtNet_t* p = _cmRtNetHandleToPtr(h);
@ -761,7 +764,7 @@ cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, unsi
return cmErrMsg(&p->err,kNodeNotFoundNetRC,"The node '%s' was not found.",cmStringNullGuard(nodeLabel)); return cmErrMsg(&p->err,kNodeNotFoundNetRC,"The node '%s' was not found.",cmStringNullGuard(nodeLabel));
if(( ep = _cmRtNetFindNodeEnd(np, rtSubIdx, endptLabel )) == NULL ) if(( ep = _cmRtNetFindNodeEnd(np, endptLabel )) == NULL )
return cmErrMsg(&p->err,kEndNotFoundNetRC,"The endpoint '%s' on '%s' on node was not found.",cmStringNullGuard(endptLabel),cmStringNullGuard(nodeLabel)); return cmErrMsg(&p->err,kEndNotFoundNetRC,"The endpoint '%s' on '%s' on node was not found.",cmStringNullGuard(endptLabel),cmStringNullGuard(nodeLabel));
hp->h = ep; hp->h = ep;
@ -773,14 +776,19 @@ cmRtNetRC_t _cmRtNetSend( cmRtNet_t* p, const cmRtNetEnd_t* ep, const void* msg,
{ {
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
unsigned dN = sizeof(cmRtNetMsg_t) + msgByteCnt; unsigned hN = sizeof(cmRtNetMsg_t);
unsigned dN = hN + msgByteCnt;
char data[ dN ]; char data[ dN ];
cmRtNetMsg_t* r = (cmRtNetMsg_t*)data; cmRtNetMsg_t* r = (cmRtNetMsg_t*)data;
r->hdr.rtSubIdx = ep->rtSubIdx; r->hdr.rtSubIdx = ep->np->rtSubIdx;
r->hdr.selId = kMsgSelRtId; r->hdr.selId = kMsgSelRtId;
r->endptId = ep->id; r->endptId = ep->id;
memcpy(data+sizeof(cmRtNetMsg_t),msg,msgByteCnt); memcpy(data+hN,msg,msgByteCnt);
// ep->np->sockaddr identifies the node on the receiving cmRtNet.
// cmRtNetMsg_t* r.endptId is then used by the receiving cmRtNet to indicate which endpoint on
// the node the incoming message should be associated with.
if( cmUdpSendTo(p->udpH, data, dN, &ep->np->sockaddr ) != kOkUdpRC ) if( cmUdpSendTo(p->udpH, data, dN, &ep->np->sockaddr ) != kOkUdpRC )
return cmErrMsg(&p->err,kUdpPortFailNetRC,"Send to node:%s endpt:%s failed.\n",cmStringNullGuard(ep->np->label),cmStringNullGuard(ep->label)); return cmErrMsg(&p->err,kUdpPortFailNetRC,"Send to node:%s endpt:%s failed.\n",cmStringNullGuard(ep->np->label),cmStringNullGuard(ep->label));
@ -798,12 +806,12 @@ cmRtNetRC_t cmRtNetSend( cmRtNetH_t h, cmRtNetEndptH_t epH, const void* msg, uns
} }
cmRtNetRC_t cmRtNetSendByLabels( cmRtNetH_t h, const cmChar_t* nodeLabel, unsigned rtSubIdx, const cmChar_t* endptLabel, const void* msg, unsigned msgByteCnt ) cmRtNetRC_t cmRtNetSendByLabels( cmRtNetH_t h, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, const void* msg, unsigned msgByteCnt )
{ {
cmRtNetRC_t rc = kOkNetRC; cmRtNetRC_t rc = kOkNetRC;
cmRtNetEndptH_t epH = cmRtNetEndptNullHandle; cmRtNetEndptH_t epH = cmRtNetEndptNullHandle;
if((rc = cmRtNetEndpointHandle(h,nodeLabel,rtSubIdx,endptLabel,&epH)) != kOkNetRC ) if((rc = cmRtNetEndpointHandle(h,nodeLabel,endptLabel,&epH)) != kOkNetRC )
return rc; return rc;
return cmRtNetSend(h,epH,msg,msgByteCnt); return cmRtNetSend(h,epH,msg,msgByteCnt);
@ -935,7 +943,7 @@ cmRtNetRC_t cmRtNetRemoteNodeEndPoint(
*labelRef = ep->label; *labelRef = ep->label;
*idRef = ep->id; *idRef = ep->id;
*rsiRef = ep->rtSubIdx; *rsiRef = ep->np->rtSubIdx;
return kOkNetRC; return kOkNetRC;
} }
@ -998,7 +1006,7 @@ void cmRtNetTest( cmCtx_t* ctx, bool mstrFl )
if( cmThreadCreate(&p->thH,_cmRtNetTestThreadFunc,p,&ctx->rpt) != kOkThRC ) if( cmThreadCreate(&p->thH,_cmRtNetTestThreadFunc,p,&ctx->rpt) != kOkThRC )
goto errLabel; goto errLabel;
if((rc = cmRtNetAlloc(ctx,&p->netH,_cmRtNetTestRecv,p)) != kOkNetRC ) if((rc = cmRtNetAlloc(ctx,&p->netH,rtSubIdx,_cmRtNetTestRecv,p)) != kOkNetRC )
goto errLabel; goto errLabel;
cmRtNetReportSyncEnable(p->netH,true); // enable sync. protocol reporting cmRtNetReportSyncEnable(p->netH,true); // enable sync. protocol reporting
@ -1006,7 +1014,7 @@ void cmRtNetTest( cmCtx_t* ctx, bool mstrFl )
if((rc = cmRtNetInitialize(p->netH, bcastAddr, localHostStr, NULL, port )) != kOkNetRC) if((rc = cmRtNetInitialize(p->netH, bcastAddr, localHostStr, NULL, port )) != kOkNetRC)
goto errLabel; goto errLabel;
if((rc = cmRtNetRegisterEndPoint(p->netH,rtSubIdx,localEndpStr, 0 )) != kOkNetRC ) if((rc = cmRtNetRegisterEndPoint(p->netH,localEndpStr, 0 )) != kOkNetRC )
goto errLabel; goto errLabel;
if( cmThreadPause(p->thH,0) != kOkThRC ) if( cmThreadPause(p->thH,0) != kOkThRC )
@ -1028,7 +1036,7 @@ void cmRtNetTest( cmCtx_t* ctx, bool mstrFl )
case 't': case 't':
{ {
if( cmRtNetSendByLabels(p->netH, remoteHostStr, rtSubIdx, remoteEndpStr, &p->msgVal, sizeof(p->msgVal)) == kOkNetRC ) if( cmRtNetSendByLabels(p->netH, remoteHostStr, remoteEndpStr, &p->msgVal, sizeof(p->msgVal)) == kOkNetRC )
p->msgVal += 1; p->msgVal += 1;
} }

View File

@ -5,6 +5,21 @@
extern "C" { extern "C" {
#endif #endif
/*
Nodes and Endpoints:
---------------------
A node corresponds to a process and owns a socket. It also has a label which is
unique among all other nodes on the network. A node also has a set of application
defined 'endpoints'. Each endpoint has a label and id that is unique among all
other endpoints on the same node. Endpoints on different nodes however may share
use the same label and id. Endpoints are used by remote senders to identify
a particular receiver which is sharing the node with other receivers. Endpoints
are therefore analogous to port numbers on sockets.
See gt/doc/notes.txt for more discussion of cmRtNet.
*/
enum enum
{ {
kOkNetRC = cmOkRC, kOkNetRC = cmOkRC,
@ -62,7 +77,8 @@ extern "C" {
// 'cbFunc' will be called within the context of cmRtNetReceive() to receive // 'cbFunc' will be called within the context of cmRtNetReceive() to receive
// incoming network messages. // incoming network messages.
cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, cmUdpCallback_t cbFunc, void* cbArg ); // rtSubIdx is the rtSubIdx of the cmRtSys which owns this cmRtNet.
cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, unsigned rtSubIdx, cmUdpCallback_t cbFunc, void* cbArg );
cmRtNetRC_t cmRtNetFree( cmRtNetH_t* hp ); cmRtNetRC_t cmRtNetFree( cmRtNetH_t* hp );
bool cmRtNetIsValid( cmRtNetH_t h ); bool cmRtNetIsValid( cmRtNetH_t h );
@ -85,7 +101,7 @@ extern "C" {
// cmRtNetInitialize(). // cmRtNetInitialize().
// Remote nodes will be able to send messages to these endpoints by // Remote nodes will be able to send messages to these endpoints by
// referring to (nodeLabel/endPtLabel) // referring to (nodeLabel/endPtLabel)
cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, unsigned rtSubIdx, const cmChar_t* endPtLabel, unsigned endPtId ); cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, const cmChar_t* endPtLabel, unsigned endPtId );
// Delete all nodes and endpoints. // Delete all nodes and endpoints.
cmRtNetRC_t cmRtNetFinalize( cmRtNetH_t h ); cmRtNetRC_t cmRtNetFinalize( cmRtNetH_t h );
@ -100,15 +116,15 @@ extern "C" {
// an cmRtSysMsgHdr_t header (See cmRtSysMsg.h). // an cmRtSysMsgHdr_t header (See cmRtSysMsg.h).
cmRtNetRC_t cmRtNetReceive( cmRtNetH_t h ); cmRtNetRC_t cmRtNetReceive( cmRtNetH_t h );
// Get an end point handle for use with cmRtNetSend. // Get a remote end point handle for use with cmRtNetSend.
cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, unsigned rtSubIdx, const cmChar_t* endptLabel, cmRtNetEndptH_t* hp ); cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, cmRtNetEndptH_t* hp );
// Send a message to a remote endpoint. // Send a message to a remote endpoint.
cmRtNetRC_t cmRtNetSend( cmRtNetH_t h, cmRtNetEndptH_t epH, const void* msg, unsigned msgByteCnt ); cmRtNetRC_t cmRtNetSend( cmRtNetH_t h, cmRtNetEndptH_t epH, const void* msg, unsigned msgByteCnt );
// Send a message to a remote endpoint. This function is a composite // Send a message to a remote endpoint. This function is a composite
// of cmRtNetEndpointHandle() and cmRtNetSend(). // of cmRtNetEndpointHandle() and cmRtNetSend().
cmRtNetRC_t cmRtNetSendByLabels( cmRtNetH_t h, const cmChar_t* nodeLabel, unsigned rtSubIdx, const cmChar_t* endptLabel, const void* msg, unsigned msgByteCnt ); cmRtNetRC_t cmRtNetSendByLabels( cmRtNetH_t h, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, const void* msg, unsigned msgByteCnt );
cmRtNetRC_t cmRtNetSendByIndex( cmRtNetH_t h, unsigned nodeIdx, unsigned endptIdx, const void* msg, unsigned msgByteCnt ); cmRtNetRC_t cmRtNetSendByIndex( cmRtNetH_t h, unsigned nodeIdx, unsigned endptIdx, const void* msg, unsigned msgByteCnt );