bool modAOS_IN_SDU_Insert::_insertWaitingInSduUnit(AOS_Transfer_Frame* frame) {
	bool success = false;

	if ( ! getAuxQueue()->is_empty() ) {
		std::pair<NetworkData*, int> auxQueueTop = getAuxData_();

		if ( auxQueueTop.second < 0 ) {
			MOD_ERROR("getAuxData_() call failed.");
		}
		else if ( ! auxQueueTop.first ) {
			MOD_ERROR("getAuxData_() returned with null data.");
		}
		else {
			ACE_Message_Block* mb = auxQueueTop.first;
			NetworkData* inSdu = dynamic_cast<NetworkData*>(mb);

			if ( ! inSdu || mb->length() != static_cast<size_t>(getInsertZoneSize()) ) {
				MOD_WARNING("Unrecognized %d-octet, non-IN_SDU data unit received on auxInput queue (inSdu ptr: %X, IZ size: %d)",
							mb->length(), inSdu, getInsertZoneSize());
				ndSafeRelease(mb);
			}
			else {
				MOD_DEBUG("%d-octet IN_SDU unit is waiting, attempting to copy to the %d-octet Insert Zone.",
					inSdu->getUnitLength(), frame->getInSduLen());

				_receivedInSduUnitCount += 1;
				_receivedInSduOctetCount += inSdu->getUnitLength();

				try {
					frame->setInsertZone(inSdu);
					success = true;
				}
				catch(const BufferOverflow& e) {
					MOD_WARNING("%d-octet IN_SDU unit could not fit into %d-octet Insert Zone, dropping.",
						inSdu->getUnitLength(), frame->getInSduLen());
				}

				ndSafeRelease(inSdu);
			}
		}
	}

	return success;
}
Пример #2
0
int modASM_Remove::svc() {
	svcStart_();
	ACE_UINT8* markerBuf = 0;
	size_t markerLen = 0;
	_rebuildMarker = true;
	NetworkData* data = 0;
	NetworkData* goodUnit = 0;
	size_t goodUnitLength = 0;
	size_t advanceLen = 0;
	size_t remainingLen = 0;
	size_t partialMarkerLen = 0;
	size_t markerOffset = 0;
	bool searching = false;

	while ( continueService() ) {
		std::pair<NetworkData*, int> queueTop = getData_();

		if ( msg_queue()->deactivated() ) break;

		if ( queueTop.second < 0 ) {
			MOD_ERROR("getData_() call failed.");
			continue;
		}
		else if ( ! queueTop.first ) {
			MOD_ERROR("getData_() returned with null data.");
			continue;
		}

		data = queueTop.first;

		_updateMarker(markerBuf, markerLen);

		MOD_DEBUG("Received a %d-octet unit to test for ASMs.", data->getUnitLength());

		while ( data->getUnitLength() ) {
			if ( ! goodUnit ) { // no unit to continue, need to find next ASM
				partialMarkerLen = markerLen - markerOffset;

				// determine if enough buffer left to find ASM
				// if not, check what's left and check for remainder in next buffer
				if ( data->getUnitLength() < partialMarkerLen ) {
					if ( _markerMatch(data->ptrUnit(), markerBuf + markerOffset, data->getUnitLength()) ) {
						// this portion is correct
						markerOffset += data->getUnitLength();
					}
					else {
						MOD_DEBUG("Missed partial ASM, resetting marker offset and bit error count.");
						incPartialMismatchCount();
						markerOffset = 0;
						_currentBitErrors = 0;
					}

					advanceLen = data->getUnitLength();
				}
				// if so, look for ASM normally
				else if ( _markerMatch(data->ptrUnit(), markerBuf + markerOffset, partialMarkerLen) ) {
					MOD_DEBUG("Found ASM.");
					_asmCount++;

					if ( searching ) _asmDiscoveredCount++;
					else _asmValidCount++;

					searching = false;
					advanceLen = partialMarkerLen;
					markerOffset = 0;
					_currentBitErrors = 0;

					// determine if entire unit can be extracted from buffer
					// if so, wrap and send
                    if ( data->getUnitLength() - partialMarkerLen >= getExpectedUnitLength() ) {
						MOD_DEBUG("Found complete unit.");
						goodUnit = data->wrapInnerPDU<NetworkData>(getExpectedUnitLength(),
							data->ptrUnit() + partialMarkerLen);
						_send(goodUnit);
						advanceLen += getExpectedUnitLength();
                    }
					// if not, create a new unit to hold it
					else {
						MOD_DEBUG("Holding partial unit for expected completion.");
						goodUnitLength = data->getUnitLength() - partialMarkerLen;
						goodUnit = new NetworkData(getExpectedUnitLength());
						goodUnit->copyUnit(goodUnit->ptrUnit(), data->ptrUnit() + partialMarkerLen, goodUnitLength);
						advanceLen += goodUnitLength;
					};
				}
				else {
					MOD_DEBUG("Missed ASM, advancing one octet at a time.");
					if (! searching ) _asmMissedCount++; // Only increment for the first miss, or after another ASM was found.
					searching = true;
					incSearchCount();

					// data->dump();
					advanceLen = 1;
					markerOffset = 0;
					_currentBitErrors = 0;
				}
			}
			else { // continuing previous unit, don't look for ASM
				remainingLen = getExpectedUnitLength() - goodUnitLength;
				// determine if remaining unit fits in buffer
				// if so, append it and send, reset goodUnit to 0
				if ( data->getUnitLength() >= remainingLen ) {
					MOD_DEBUG("Completing partial unit with newly received data.");
					goodUnit->copyUnit(goodUnit->ptrUnit() + goodUnitLength, data->ptrUnit(),
						remainingLen);
					_send(goodUnit);
					advanceLen = remainingLen;
				}

				// if not, append it and don't send
				else {
					MOD_DEBUG("Adding to partial unit but will complete later.");

					goodUnit->copyUnit(goodUnit->ptrUnit() + goodUnitLength, data->ptrUnit(),
						data->getUnitLength());
					goodUnitLength += data->getUnitLength();
					advanceLen = data->getUnitLength();
				}
			}

			// advance read pointer by length just used up
			data->rd_ptr(advanceLen);
			MOD_DEBUG("Buffer length is now %d.", data->getUnitLength());
		}

		ndSafeRelease(data);
	}

	return svcEnd_();
}
Пример #3
0
bool modAOS_OCF_Insert::_insertWaitingReport(AOS_Transfer_Frame* frame) {
	bool success = false;

	if ( ! getAuxQueue()->is_empty() ) {
		std::pair<NetworkData*, int> auxQueueTop = getAuxData_();

		if ( auxQueueTop.second < 0 ) {
			MOD_ERROR("getAuxData_() call failed.");
		}
		else if ( ! auxQueueTop.first ) {
			MOD_ERROR("getAuxData_() returned with null data.");
		}
		else {
			ACE_Message_Block* mb = auxQueueTop.first;

			TC_Comm_Link_Control_Word* clcw = dynamic_cast<TC_Comm_Link_Control_Word*>(mb);

			if (clcw) {
				MOD_DEBUG("Received a Communications Link Control Word.");

				_receivedReportUnitCount += 1;
				_receivedReportOctetCount += clcw->getUnitLength();

				try {
					frame->setCLCW(clcw);
					success = true;
				}
				catch (const MissingField& e) {
					MOD_WARNING("Attempt to insert CLCW into frame without an OCF, dropping the CLCW.");
				}

				delete clcw;
			}
			else {
				NetworkData* ocf = dynamic_cast<NetworkData*>(mb);

				if ( ! ocf || mb->length() != AOS_Transfer_Frame::spanOperationalControlField ) {
					MOD_WARNING("Unrecognized %d-octet, non-Report data unit received on auxiliary queue.", mb->length());

					ndSafeRelease(mb);
				}
				else {
					MOD_DEBUG("Type-2 Report is waiting, attempting to copy to the Operational Control Field.");

					_receivedReportUnitCount += 1;
					_receivedReportOctetCount += ocf->getUnitLength();

					try {
						frame->setType2ReportData(ocf->ptrUnit());
						success = true;
					}
					catch (const MissingField& e) {
						MOD_WARNING("Attempt to insert Type-2 Report into AOS Transfer Frame without an OCF, dropping the report.");
					}
					catch (const NetworkData::MalformedPayload& e) {
						MOD_WARNING("Attempt to insert malformed Type-2 Report into AOS Transfer Frame, dropping the report.");
					}

					ndSafeRelease(ocf);
				}
			}
		}
	}

	return success;
}