nw_messageHolder nw_plugDataBufferGetNextMessageHolder( nw_plugDataBuffer buffer, nw_messageHolder prevMessageHolder, nw_bool wholeMessagesOnly) { nw_messageHolder result = NULL; nw_bool isFragmented; nw_bool isLast; nw_bool isTerminator; NW_CONFIDENCE(buffer != NULL); if (prevMessageHolder != NULL) { if (!nw_plugDataBufferIsLastMessageHolder(buffer, prevMessageHolder)) { /* Get next from previous */ result = (nw_messageHolder)NW_ALIGN(NW_PLUGDATABUFFER_DATA_ALIGNMENT, UI(NW_MESSAGEHOLDER_DATA(prevMessageHolder)) + nw_messageHolderGetLength(prevMessageHolder)); } } else { /* Get first */ result = NW_PLUGDATABUFFER_FIRSTMESSAGE(buffer); } if ((result != NULL) && (wholeMessagesOnly)) { isFragmented = nw_plugBufferGetFragmentedFlag(nw_plugBuffer(buffer)); if (isFragmented) { isLast = nw_plugDataBufferIsLastMessageHolder(buffer, result); if (isLast) { result = NULL; } } if (result != NULL) { isTerminator = nw_plugBufferGetTerminatorFlag(nw_plugBuffer(buffer)); if (isTerminator && (prevMessageHolder == NULL)) { /* Skip this first message because it is the terminator of a * previous message */ result = (nw_messageHolder)NW_ALIGN(NW_PLUGDATABUFFER_DATA_ALIGNMENT, UI(NW_MESSAGEHOLDER_DATA(result)) + nw_messageHolderGetLength(result)); } } } return result; }
nw_bool nw_plugDataBufferIsLastMessageHolder( nw_plugDataBuffer buffer, nw_messageHolder messageHolder) { nw_bool result = FALSE; nw_seqNr fragmentLength; nw_seqNr msgLength; nw_seqNr offset; NW_CONFIDENCE(buffer != NULL); if (messageHolder != NULL) { fragmentLength = nw_plugBufferGetLength(nw_plugBuffer(buffer)); msgLength = nw_messageHolderGetLength(messageHolder); offset = UI(messageHolder) - UI(buffer) + sizeof(messageHolder->length); result = ((offset + NW_ALIGN(NW_PLUGDATABUFFER_DATA_ALIGNMENT, msgLength)) == fragmentLength); } return result; }
void nw_plugChannelInitialize( nw_plugChannel channel, nw_seqNr seqNr, nw_networkId nodeId, nw_communicationKind communication, nw_plugPartitions partitions, nw_userData *userDataPtr, const char *pathName, nw_onFatalCallBack onFatal, c_voidp onFatalUsrData) { nw_size fragmentLength; nw_bool reliable; nw_bool controlNeeded; static sk_portNr sendingPortNr = NWCF_DEF(PortNr); static sk_portNr receivingPortNr = NWCF_DEF(PortNr); sk_portNr newPortNr; nw_plugInterChannel *interChannelPtr = (nw_plugInterChannel *)userDataPtr; char *defaultPartitionAddress; /* Simple attributes */ channel->name = nw_stringDup(pathName); channel->Id = seqNr; channel->nodeId = nodeId; channel->communication = communication; channel->partitions = partitions; /* Attributes to be read from config */ /* QoS-es*/ reliable = NWCF_SIMPLE_ATTRIB(Bool, pathName, reliable); if (reliable) { channel->reliabilityOffered = NW_REL_RELIABLE; controlNeeded = TRUE; /* Create object for inter-channel communication */ nw_plugInterChannelIncarnate(interChannelPtr, pathName); channel->interChannelComm = *interChannelPtr; } else { channel->reliabilityOffered = NW_REL_BEST_EFFORT; controlNeeded = FALSE; /* NO object needed for inter-channel communication */ channel->interChannelComm = NULL; } /* Default, to be implemented */ channel->priorityOffered = NW_PRIORITY_UNDEFINED; channel->latencyBudgetOffered = NW_LATENCYBUDGET_UNDEFINED; /* Network fragment length */ fragmentLength = (nw_size)NWCF_SIMPLE_PARAM(Size, pathName, FragmentSize); /* CHECKME, NWCF_MIN(FragmentSize) must be larger dealing with encryption */ if (fragmentLength < NWCF_MIN(FragmentSize)) { NW_REPORT_WARNING_3("initializing network", "Channel \"%s\": requested value %u for fragment size is too small, " "using %u instead", pathName, fragmentLength, NWCF_MIN(FragmentSize)); fragmentLength = NWCF_MIN(FragmentSize); } else if(fragmentLength > NWCF_MAX(FragmentSize)) { NW_REPORT_WARNING_3("initializing network", "Channel \"%s\": requested value " PA_SIZEFMT " for fragment size is too big, " "using %u instead", pathName, fragmentLength, NWCF_MAX(FragmentSize)); fragmentLength = NWCF_MAX(FragmentSize); } /* FIXME, this rounds up to multiple of 4, but it should round down to * meet network constraints (??) */ /* round to lowest NW_FRAG_BOUNDARY multiplication higher than * fragmentLength */ channel->fragmentLength = NW_ALIGN(NW_PLUGDATABUFFER_ALIGNMENT, (nw_length)fragmentLength); /* What is the base adress of the socket wee need ? */ nw_plugPartitionsGetDefaultPartition(partitions, &defaultPartitionAddress, NULL /* SecurityProfile not of interest */ ); switch (communication) { case NW_COMM_SEND: newPortNr = NWCF_DEFAULTED_PARAM(ULong, pathName, PortNr, sendingPortNr); if (newPortNr == sendingPortNr) { sendingPortNr+=2; } channel->socket = nw_socketSendNew(defaultPartitionAddress, newPortNr, controlNeeded, pathName); break; case NW_COMM_RECEIVE: newPortNr = NWCF_DEFAULTED_PARAM( ULong, pathName, PortNr, receivingPortNr); if (newPortNr == receivingPortNr) { receivingPortNr+=2; } channel->socket = nw_socketReceiveNew(defaultPartitionAddress, newPortNr, controlNeeded, pathName); break; default: NW_CONFIDENCE(FALSE); break; } channel->messageBox = nw_messageBoxNew(); channel->onFatal = onFatal; channel->onFatalUsrData = onFatalUsrData; channel->reconnectAllowed = NWCF_SIMPLE_ATTRIB(Bool,NWCF_ROOT(General) NWCF_SEP NWCF_NAME(Reconnection),allowed); channel->crc = ut_crcNew(UT_CRC_KEY); }