/* * Copyright (c) 2025 Real-Time Innovations, Inc. All rights reserved. * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or revisions thereof, * must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef commend_writerService_h #define commend_writerService_h #ifndef reda_table_h #include "reda/reda_table.h" #endif #ifndef reda_weakReference_h #include "reda/reda_weakReference.h" #endif #ifndef reda_inlineList_h #include "reda/reda_inlineList.h" #endif #ifndef osapi_ntptime_h #include "osapi/osapi_ntptime.h" #endif #ifndef property_propertyNames_h #include "property/property_propertyNames.h" #endif #ifndef event_jobDispatcher_h #include "event/event_jobDispatcher.h" #endif #ifndef mig_rtps_h #include "mig/mig_rtps.h" #endif #ifndef mig_generator_h #include "mig/mig_generator.h" #endif #ifndef commend_dll_h #include "commend/commend_dll.h" #endif #ifndef commend_common_h #include "commend/commend_common.h" #endif #ifndef commend_writerStatistics_h #include "commend/commend_writerStatistics.h" #endif #ifdef __cplusplus extern "C" { #endif /* Doxygen file-level documentation =====================================*/ /*e \file \brief COMMENDWriterService *interface*--as in no implementation. */ /*e \defgroup COMMENDWriterServiceModule COMMENDWriterService \ingroup COMMENDModule @brief This COMMEND layer submodule defines writer services. Detailed description on writer services. */ /*e \defgroup COMMENDWriterServiceWriterActivityListenerModule COMMENDWriterServiceWriterActivityListener \ingroup COMMENDWriterServiceModule @brief Brief description of writer activity listeners. Detailed description of writer activity listeners. */ /*e \defgroup COMMENDWriterServiceWriterSampleListenerModule COMMENDWriterServiceWriterSampleListener \ingroup COMMENDWriterServiceModule @brief Brief description of writer sample listeners. Detailed description of writer sample listeners. */ /* * This property is used only for testing purposes to suppress * the reception of AppAck messages. * * The property can be disabled/enabled at run-time */ #define COMMEND_WRITER_SUPPRESS_APPACK \ PROPERTY_NAME_DDS_DATA_WRITER_SUPPRESS_APPACK struct COMMENDWriterService; struct COMMENDWriterServiceWriterSampleListener; struct COMMENDWriterServiceWriterActivityListener; struct COMMENDFilterStatus; struct COMMENDWriterServiceTransportPlugins { int length; /* array's length */ NDDS_Transport_Plugin **plugins; /* array of plugin ptrs */ }; #define COMMEND_WRITER_SERVICE_TRANSPORT_PLUGINS_DEFAULT \ { \ 0, /* length */ \ NULL, /* plugins */ \ } /*e \ingroup COMMENDWriterServiceWriterListenerModule * Should be large enough to accommodate any listener param. * * Currently we are storing in the COMMENDWriterServiceWriterListenerStorage * structure the following: * * struct REDAWeakReference (pointer + int + unsigned int) * RTI_INT32 * * PRESPsServiceTester_testListenerStorageSize tests that the storage has * sufficient space for all of the above. * Note that the storage also contains a padding element to ensure that we are * always aligned on both 32-bit and 64-bit architectures. */ #define COMMEND_WRITER_SERVICE_WRITER_LISTENER_STORAGE_LENGTH (5) /*e \ingroup COMMENDWriterService * Number of remote readers on the same locator to filter for */ #define COMMEND_WRITER_LOCATOR_MAX_REMOTE_READER (4) /*e \ingroup COMMENDWriterServiceWriterActivityListenerModule * In order to avoid having to manually calculate the offsets required to access * the fields stored within the COMMENDWriterServiceWriterListenerStorage * structure we create a struct which we can cast it to. */ struct COMMENDWriterServiceWriterListenerData { /* The weak reference to the RW area of the writer record */ struct REDAWeakReference rwWriterWR; /* The session ID of the writer */ RTI_INT32 sessionId; }; struct COMMENDWriterServiceWriterListenerStorage { /* field containing the actual listener storage */ void *field[COMMEND_WRITER_SERVICE_WRITER_LISTENER_STORAGE_LENGTH]; /* * We need to force the alignment of this structure to be on an 8-byte * boundary. This is because we cast other structures on top of this, and * on 32-bit architectures the field member could cause this structure to be * aligned on a 4-byte boundary. */ RTI_UINT64 _padding; }; #define COMMENDWriterServiceWriterListenerStorage_INITIALIZER \ { \ { NULL, NULL, NULL, NULL, NULL }, /* field */ \ 0 /* _padding */ \ } /*e \ingroup COMMENDWriterWriterServiceSampleListenerModule * onGetData listener prototype. Called to get user data. * * @pre When the commend needs to re-send some data (a response to an ack), * it will call this callback to get user data. * * @post If RTI_FALSE, the callback failed, and commend should ignore all * out params. If RTI_TRUE, out params are correctly set. If the data is * available, it will be in dataToBeWritten, and dataValid will be TRUE. All * other out params are properly set. * * @param listener \b In. Object interested in the callback. * @param dataToBeWritten \b Out. User data. * @param dataValid \b Out. Whether the user data is valid. * @param firstRelevantSn \b Out. First relevant sequence number. The value * should be the first available sn currently kept in the queue. In the case * the writer has no data, the firstRelevantSn should be the first future sn. * @param firstRelevantVirtualSn \b Out. First relevant virtual sequence number. * @param nextRelevantSn \b Out. The next relevant sn. When there is a gap after * the requested sn, nextRelevantSn will be the first sn after the gap. When the * the request sn is the last, the nextRelevantSn will be the same as the * reuqested sn. Otherwise, the nextRelevantSn will be the requestSn + 1. In the * case the writer has no data, the nextRelevantSn should be the last sn used. * @param keepDuration \b In. Updated keepDuration for congestion-induced data * request. Optional. * @param storage \b In. The istener storage cached. * @param requestSn \b In. The sn of the requested data. * @param lateJoinerLastHistoricalVirtualSn \b In. The virtual sn of the last * sample published before the reader was matched. Is NULL when requested * samples should not be GAPed be based on this Sn. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnDataRequestCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, struct MIGGeneratorSample **sample, RTIBool *dataValid, struct REDASequenceNumber *firstRelevantSn, struct REDASequenceNumber *nextRelevantSn, struct REDASequenceNumber *firstRelevantVirtualSn, struct REDASequenceNumber *nextRelevantVirtualSn, struct RTINtpTime *ackDelay, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct REDASequenceNumber *requestSn, const struct REDASequenceNumber *lateJoinerLastHistoricalVirtualSn, int filterIndex, struct COMMENDFilterStatus *filterStatus, const struct RTINtpTime *now_in, const struct MIGRtpsGuid *remoteReaderVirtualGuid, struct REDAWorker *worker); /*e \ingroup COMMENDWriterWriterServiceSampleListenerModule * onDataLoanFinish listener prototype. Called to return the loan on user data. * * @pre When the commend needs to return the loan on user data previously * gotten via the onDataRequest callback, it will call this callback. * * @post The sample has been returned and should no longer be accessed. * * @param listener \b In. Object interested in the callback. * @param sample \b In. User data. * @param storage \b In. The istener storage cached. * @param worker \b In. */ typedef void ( *COMMENDWriterServiceWriterSampleListenerOnDataLoanFinishCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, struct MIGGeneratorSample *sample, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterActivityListenerModule * onTimeout listener prototype. Called when a remote reader times out. * * @pre The writer will send out periodic heartbeat. When there is no repsonse * (ack) for hbRetriesMax number of hearbeats, the remote reader is timeout. * This callback is called. * * @post Should return void (TODO). The listener has got the info. The commend * will keep sending periodic heartbeat to this remote reader, so that it may * come up later. But writer will on longer waits for ack, or even blocks * because of no reponse from this remote reader. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The istener storage cached. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterActivityListenerOnRemoteReaderInactiveCallback)( const struct COMMENDWriterServiceWriterActivityListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterActivityListenerModule * onTimeout listener prototype. Called when a remote reader becomes active. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The istener storage cached. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterActivityListenerOnRemoteReaderActiveCallback)( const struct COMMENDWriterServiceWriterActivityListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * onFirstUnackedSnChange listener prototype. Called when last fully acked * sequence number (or firstUnackedSn) is changed. * * @pre When the writer receives acks from all remote readers (except the * timeout ones) for up to certain sn, it's the lastFullyAckedSn, and * firstUnackedSn = lastFullyAckedSn + 1. When this value is changed (moves * forward), the callback is called. * * @post Should be void (TODO). Listener has got the info. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The istener storage cached. * @param firstUnackedSn \b In. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnFirstUnackedSnChangeCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, struct REDASequenceNumber *firstUnackedVirtualSn, /* output parameter */ const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct MIGRtpsGuid *readerVirtualGuid, const RTIBool durSubOnly, const struct REDASequenceNumber *firstUnackedSn, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * OnFirstUnackedSnChangeByRemoteReader listener prototype. * Called when last fully acked sequence number (or firstUnackedSn) is changed * for one remote reader. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The listener storage cached. * @param readerGuid \b In. Reader GUID (non-virtual). * @param firstUnackedSn \b In. The first unacked sn (non-virtual). * @param worker \b In. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnFirstUnackedSnChangeByRemoteReader)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct MIGRtpsGuid *readerGuid, const struct REDASequenceNumber *firstUnackedSn, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * onFirstUnackedSnRequest listener prototype. Called when last fully acked * sequence number is requested and/or may change. * * @pre When * * When the writer receives acks from all remote readers (except the * timeout ones) for up to certain sn, it's the lastFullyAckedSn, and * firstUnackedSn = lastFullyAckedSn + 1. When this value is changed (moves * forward), the callback is called. * * @post Should be void (TODO). Listener has got the info. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The istener storage cached. * @param firstUnackedSn \b In. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnFirstNonElapsedSnUpdateCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDASequenceNumber *firstNonElapsedSn, struct RTINtpTime *firstNonElapsedTs, struct RTINtpTime *ackDelay, const struct RTINtpTime *now, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * onWriterInfoListRequest listener prototype. * Called when periodic onSendHeartbeatVirtual event is triggered * * @pre * * @post * * @param listener \b In. Object interested in the callback. * @param storage \b In. The listener storage cached. * @param list \b Out. Pointer to REDAInlineList of MIGRtpsVirtualWriterInfo * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnWriterInfoListRequestCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct MIGRtpsWriterInfoList **list, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnKeepDurationChangeCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct RTINtpTime *ackDelay, const struct RTINtpTime *now, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnSerializeSampleCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct MIGGeneratorSample *sample, RTIEncapsulationId encapsulationId, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnReturnSerializationBufferCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct MIGGeneratorSample *sample, RTIEncapsulationId encapsulationId, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnDestinationUnreachableCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct MIGRtpsGuid *readerGuid, const struct RTINetioLocator *destination, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnSendWindowChangeCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, RTI_INT32 *samplesPerHb, RTI_INT32 sendWindow, struct REDAWorker *worker); /*e \ingroup COMMENDReaderServiceReaderSampleListenerModule * OnAppAck callback for strict reliable writer sample listener * with application-level acknowledgement * * This callback is called when an application-level * acknowledgement message (APP_ACK) has been received. * * @param listener \b In. Object interested in the callback. * @param appAckConfIn \b In. An iterator that allows the user to access * the contents of the APP_ACK message. * @param storage \b In. The listener storage cached. * @param worker \b In. * * @return void * * @see COMMENDWriterServiceWriterSampleListener */ typedef RTIBool (*COMMENDWriterServiceWriterSampleListenerOnAppAckCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct MIGRtpsAppAck *appAckIn, const struct MIGRtpsGuid *remoteReaderGuid, const struct MIGRtpsGuid *remoteReaderVirtualGuid, const struct RTINtpTime *now, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * onBeAsynchPubCompleted listener prototype. Called when an asynchronously * published sample is fully published by the BEST EFFORT writer. In other * words, this is to confirm * with upper layers that the 'fresh send' of this sample has completed. * Only used for asynchronous BEST EFFORT writers. * * COMMEND guarantees to call this callback with an increasing completedSn only. * * @pre When the asynchronous BEST EFORT writer completes its initial 'fresh * send', the callback is called. * * @post Should be void (TODO). Listener has got the info. * * @param listener \b In. Object interested in the callback. * @param storage \b In. The istener storage cached. * @param completedSn \b In. * @param includingPrevious \b In. If true, then all samples < completedSn is * also considered complete. We make this distinction b/c searching for * previous samples is slower. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnBeAsynchPubCompletedCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct REDASequenceNumber *completedSn, RTIBool includingPrevious, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterActivityListenerModule * onRemoteState listener prototype. Called to decide when to respond * to the state request. * * @pre When the writer receives an ACK without final-bit set, or with final-bit * set but not acked to the last sn, the writer MUST re-send data, along with * hb. This callback is called to decide when to do the resending. * * @post If RTI_FALSE, re-send immediately. Ignore all out params. If RTI_TRUE, * shedule a postponed re-send event, using nextReponseTime and snooze. * * @param listener \b In. Object interested in teh callback. * @param nextResponseTime \b Out. The time to response to state request. * @param snooze \b Out. Relative time. Can be zero. * @param now \b In. Current time. * @param storage \b In. The listener storage cached. * @param worker \b In. * * @return RTI_TRUE if it's a delayed response. Immediate response otherwise. */ typedef RTIBool ( *COMMENDWriterServiceWriterActivityListenerOnStateRequestCallback)( const struct COMMENDWriterServiceWriterActivityListener *listener, struct RTINtpTime *nextResponseTime, struct RTINtpTime *snooze, const struct RTINtpTime *now, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterActivityListenerOnRemoteReaderAckModeChangedCallback)( const struct COMMENDWriterServiceWriterActivityListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, RTIBool ackEnabledReaderPresent, RTIBool ackDisabledReaderPresent, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceWriterSampleListenerModule * OnQueueUpdate listener prototype. Called to prune the samples in the queue * with expired lifespan, whenever heartbeat is sent out or on periodic HB * event. * * @param listener \b In. Object interested in the callback. * @param firstSn \b Out. Optional, to return the new firstSn * @param firstVirtualSn \b Out. Optional, to return the new firstVirtualSn * @param storage \b In. The listener storage cached. * @param includingPrevious \b In. If true, then all samples < completedSn is * also considered complete. We make this distinction b/c searching for * previous samples is slower. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool ( *COMMENDWriterServiceWriterSampleListenerOnQueueUpdateCallback)( const struct COMMENDWriterServiceWriterSampleListener *listener, struct REDASequenceNumber *firstSn, struct REDASequenceNumber *firstVirtualSn, const struct COMMENDWriterServiceWriterListenerStorage *storage, struct REDAWorker *worker); struct COMMENDWriterServiceWriterSampleListener { COMMENDWriterServiceWriterSampleListenerOnDataRequestCallback onDataRequest; COMMENDWriterServiceWriterSampleListenerOnDataLoanFinishCallback onDataLoanFinish; COMMENDWriterServiceWriterSampleListenerOnFirstUnackedSnChangeCallback onFirstUnackedSnChange; COMMENDWriterServiceWriterSampleListenerOnFirstUnackedSnChangeByRemoteReader onFirstUnackedSnChangeByRemoteReader; COMMENDWriterServiceWriterSampleListenerOnBeAsynchPubCompletedCallback onBeAsynchPubCompleted; COMMENDWriterServiceWriterSampleListenerOnFirstNonElapsedSnUpdateCallback onFirstNonElapsedSnUpdate; COMMENDWriterServiceWriterSampleListenerOnKeepDurationChangeCallback onKeepDurationChange; COMMENDWriterServiceWriterSampleListenerOnSerializeSampleCallback onSerializeSample; COMMENDWriterServiceWriterSampleListenerOnReturnSerializationBufferCallback onReturnSerializationBuffer; COMMENDWriterServiceWriterSampleListenerOnDestinationUnreachableCallback onDestinationUnreachable; COMMENDWriterServiceWriterSampleListenerOnSendWindowChangeCallback onSendWindowChange; COMMENDWriterServiceWriterSampleListenerOnQueueUpdateCallback onQueueUpdate; COMMENDWriterServiceWriterSampleListenerOnAppAckCallback onAppAck; COMMENDWriterServiceWriterSampleListenerOnWriterInfoListRequestCallback onWriterInfoListRequest; }; struct COMMENDWriterServiceWriterActivityListener { COMMENDWriterServiceWriterActivityListenerOnRemoteReaderInactiveCallback onRemoteReaderInactive; COMMENDWriterServiceWriterActivityListenerOnRemoteReaderActiveCallback onRemoteReaderActive; COMMENDWriterServiceWriterActivityListenerOnStateRequestCallback onStateRequest; COMMENDWriterServiceWriterActivityListenerOnRemoteReaderAckModeChangedCallback onRemoteReaderAckModeChanged; }; struct COMMENDWriterServiceWriterStatusListener; typedef RTIBool ( *COMMENDWriterServiceWriterStatusListenerOnNewWriterLocatorPairCallback)( const struct COMMENDWriterServiceWriterStatusListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const MIGRtpsObjectId localWriterOid, const struct RTINetioLocator *locator, struct REDAWorker *worker); typedef RTIBool ( *COMMENDWriterServiceWriterStatusListenerOnDeletedWriterLocatorPairCallback)( const struct COMMENDWriterServiceWriterStatusListener *listener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const MIGRtpsObjectId localWriterOid, const struct RTINetioLocator *locator, struct REDAWorker *worker); struct COMMENDWriterServiceWriterStatusListener { COMMENDWriterServiceWriterStatusListenerOnNewWriterLocatorPairCallback onNewWriterLocatorPair; COMMENDWriterServiceWriterStatusListenerOnDeletedWriterLocatorPairCallback onDeletedWriterLocatorPair; }; struct COMMENDFilterStatusEx { /*e Filter index status: 0=passed 1=nopass */ RTI_UINT32 status; /*e Filter index state: 1=invalid, 0=valid */ RTI_UINT32 state; }; struct COMMENDFilterStatus { /*e Filter index status: 0=passed 1=nopass */ RTI_UINT32 status; /*e Filter index state: 1=invalid, 0=valid */ RTI_UINT32 state; /*e Extended filter status for more then 32 readers. * Note that the first entry has special meaning: * * extended[0].status is the msx number of elements in the array * * extended[0].state is the highest index currenty in use. This is * to avoid having to iterate over the entire array when only some of the * entries are used. */ struct COMMENDFilterStatusEx *_extended; /* Reader lists to support optimized writer side filtering */ /* List of readers whose filters pass the sample */ struct REDAInlineList *_passedReaders; /* List of readers for which writer side filtering is not being performed */ struct REDAInlineList *_notFilteredReaders; }; #define COMMEND_FILTER_INDEX_MAX 32 #define COMMEND_FILTER_STATUS_NEW \ { \ 0, 0, NULL, NULL, NULL \ } #define COMMEND_FILTER_STATUS_NO_FILTER_NEW \ { \ 0, 0, NULL, NULL, NULL \ } #define COMMEND_FILTER_INDEX_REUSE 0x7ffffffe #define COMMEND_FILTER_INDEX_INVALID 0x7fffffff #define COMMEND_FILTER_MAX_FILTERS ((COMMEND_FILTER_INDEX_INVALID) -2) #define COMMEND_FILTER_ALL_INDEX_INVALID 0xffffffff #define COMMEND_FILTER_STATUS_INVALID \ { \ 0, COMMEND_FILTER_ALL_INDEX_INVALID, NULL, NULL \ } #define COMMENDFilterStatus_clear(me__) \ { \ RTI_UINT32 i__; \ (me__)->status = 0; \ (me__)->state = COMMEND_FILTER_ALL_INDEX_INVALID; \ if ((me__)->_extended) { \ (me__)->_extended[0].state = 0; \ for (i__ = 1; i__ < (me__)->_extended[0].status; ++i__) { \ (me__)->_extended[i__].status = 0; \ (me__)->_extended[i__].state = \ COMMEND_FILTER_ALL_INDEX_INVALID; \ } \ } \ } #define COMMENDFilterStatus_clearExtension(me__, start_index__) \ { \ RTI_UINT32 i__; \ for (i__ = start_index__; i__ < (me__)->_extended[0].status; ++i__) { \ (me__)->_extended[i__].status = 0; \ (me__)->_extended[i__].state = COMMEND_FILTER_ALL_INDEX_INVALID; \ } \ } #define COMMENDFilterStatus_clearSampleStatus(me__) \ { \ RTI_UINT32 i__; \ (me__)->status = 0; \ if ((me__)->_extended) { \ for (i__ = 1; i__ < (me__)->_extended[0].status; ++i__) { \ (me__)->_extended[i__].status = 0; \ } \ } \ } #define COMMENDFilterStatus_droppedSampleStatus(me__) \ { \ RTI_UINT32 i__; \ (me__)->status = 0xffffffff; \ if ((me__)->_extended) { \ for (i__ = 1; i__ < (me__)->_extended[0].status; ++i__) { \ (me__)->_extended[i__].status = 0xffffffff; \ } \ } \ } #define COMMENDFilterStatus_arraySize(__max_index) \ (((__max_index) / COMMEND_FILTER_INDEX_MAX) + 1) #define COMMENDFilterStatus_isInvalid(__me) \ (__me->state == COMMEND_FILTER_ALL_INDEX_INVALID) \ && (__me->_extended == NULL) extern COMMENDDllExport RTIBool COMMENDFilterStatus_init(struct COMMENDFilterStatus *me, RTI_UINT32 maxIndex); extern COMMENDDllExport RTIBool COMMENDFilterStatus_extend(struct COMMENDFilterStatus *me, RTI_UINT32 maxIndex); #define COMMENDFilterStatus_finalize(__me) \ { \ if ((__me)->_extended) { \ RTIOsapiHeap_freeArray((__me)->_extended); \ (__me)->_extended = NULL; \ } \ } #define COMMENDFilterStatus_dropSample(__me, __bitnum) \ (((__bitnum) < COMMEND_FILTER_INDEX_MAX) \ ? ((__me)->status |= ((RTI_UINT32) 1 << (__bitnum))) \ : ((__me)->_extended[(__bitnum) / COMMEND_FILTER_INDEX_MAX] \ .status |= \ ((RTI_UINT32) 1 << ((__bitnum) % COMMEND_FILTER_INDEX_MAX)))) #define COMMENDFilterStatus_passSample(__me, __bitnum) \ (((__bitnum) < COMMEND_FILTER_INDEX_MAX) \ ? ((__me)->status &= ~((RTI_UINT32) 1 << (__bitnum))) \ : ((__me)->_extended[(__bitnum) / COMMEND_FILTER_INDEX_MAX] \ .status &= \ ~((RTI_UINT32) 1 << ((__bitnum) % COMMEND_FILTER_INDEX_MAX)))) #define COMMENDFilterStatus_invalidateIndex(__me, __bitnum) \ ((__bitnum < COMMEND_FILTER_INDEX_MAX) \ ? ((__me)->state |= (1U << (__bitnum))) \ : ((__me)->_extended[(__bitnum) / COMMEND_FILTER_INDEX_MAX] \ .state |= \ (1U << (__bitnum % COMMEND_FILTER_INDEX_MAX)))); \ { \ RTI_UINT32 _i; \ if (((__me)->_extended != NULL) \ && ((__me)->_extended[0].state \ == (RTI_UINT32) (__bitnum) / COMMEND_FILTER_INDEX_MAX)) { \ for (_i = (__me)->_extended[0].status - 1; \ ((_i > 0) \ && ((__me)->_extended[_i].state \ == COMMEND_FILTER_ALL_INDEX_INVALID)); \ --_i) \ ; \ (__me)->_extended[0].state = _i; \ } \ } #define COMMENDFilterStatus_validateIndex(__me, __bitnum) \ if (((__me)->_extended != NULL) \ && ((__me)->_extended[0].state \ <= ((RTI_UINT32) (__bitnum)) / COMMEND_FILTER_INDEX_MAX)) { \ (__me)->_extended[0].state = \ (RTI_UINT32) (__bitnum) / COMMEND_FILTER_INDEX_MAX; \ } \ if ((__bitnum) < COMMEND_FILTER_INDEX_MAX) { \ (__me)->state &= ~((RTI_UINT32) 1 << (__bitnum)); \ } else if ((__me)->_extended != NULL) { \ (__me)->_extended[(__bitnum) / COMMEND_FILTER_INDEX_MAX].state &= \ ~((RTI_UINT32) 1 << ((__bitnum) % COMMEND_FILTER_INDEX_MAX)); \ } extern COMMENDDllExport RTIBool COMMENDFilterStatus_samplesAreDropped(struct COMMENDFilterStatus *me); extern COMMENDDllExport RTIBool COMMENDFilterStatus_allIndicesAreInvalid(struct COMMENDFilterStatus *me); extern COMMENDDllExport RTIBool COMMENDFilterStatus_allIndicesAreValid(struct COMMENDFilterStatus *me); #define COMMENDFilterStatus_sampleIsDropped(__me, __index) \ ((__index < COMMEND_FILTER_INDEX_MAX) \ ? ((__me)->status & ((RTI_UINT32) 1 << (__index))) \ : ((__me)->_extended[(__index) / COMMEND_FILTER_INDEX_MAX].status \ & ((RTI_UINT32) 1 << (__index % COMMEND_FILTER_INDEX_MAX)))) #define COMMENDFilterStatus_indexIsValid(__me, __index) \ (((__index) == COMMEND_FILTER_INDEX_INVALID) \ ? RTI_FALSE \ : ((((__index) < COMMEND_FILTER_INDEX_MAX) \ ? (((__index) >= 0) \ && !((__me)->state \ & ((RTI_UINT32) 1 << (__index)))) \ : (((__index) >= 0) \ && !((__me)->_extended \ [(__index) \ / COMMEND_FILTER_INDEX_MAX] \ .state \ & ((RTI_UINT32) 1 \ << ((__index) \ % COMMEND_FILTER_INDEX_MAX))))))) #define COMMENDFilterStatus_indexInRange(__index) \ (__index != COMMEND_FILTER_INDEX_INVALID) /* NOTE: The copy utility doesnot copy the reader lists but instead sets them to * NULL */ extern COMMENDDllExport RTIBool COMMENDFilterStatus_copy( struct COMMENDFilterStatus *out, const struct COMMENDFilterStatus *in); /* NOTE: The compare utility doesnot consider the reader lists */ extern COMMENDDllExport RTIBool COMMENDFilterStatus_equal( const struct COMMENDFilterStatus *left, const struct COMMENDFilterStatus *right); extern COMMENDDllExport RTI_UINT32 COMMENDFilterStatus_allocateIndex( struct COMMENDFilterStatus *me, RTI_UINT32 limit); #define COMMENDFilterStatus_freeIndex(__me, __bitnum) \ ((__bitnum < COMMEND_FILTER_INDEX_MAX) \ ? ((__me)->state |= (1U << (__bitnum))) \ : ((__me)->_extended[(__bitnum) / COMMEND_FILTER_INDEX_MAX] \ .state |= \ (1U << (__bitnum % COMMEND_FILTER_INDEX_MAX)))) struct COMMENDWriterServiceProperty { /* local writer table property */ struct REDATableProperty localTable; /* remote reader table property */ struct REDATableProperty remoteTable; /* writer group table property */ struct REDATableProperty groupTable; /*e Max number of destinations per send. Should >= COMMEND_COMMON_APP_IPADDRESS_COUNT_MAX */ int destinationFanoutMax; int statsRemoteReaderFanoutMax; }; #define COMMEND_WRITER_SERVICE_PROPERTY_DEFAULT \ { \ /* localTable */ \ { { 16, \ REDA_FAST_BUFFER_POOL_UNLIMITED, \ REDA_FAST_BUFFER_POOL_UNLIMITED }, \ 1 }, /* remoteTable */ \ { { 16, \ REDA_FAST_BUFFER_POOL_UNLIMITED, \ REDA_FAST_BUFFER_POOL_UNLIMITED }, \ 1 }, /* groupTable */ \ { { 16, \ REDA_FAST_BUFFER_POOL_UNLIMITED, \ REDA_FAST_BUFFER_POOL_UNLIMITED }, \ 1 }, \ COMMEND_COMMON_APP_IPADDRESS_COUNT_MAX, /* destinationFanoutMax \ */ \ 16 /* statsRemoteReaderFanoutMax */ \ } struct COMMENDTransportEncapsulationInfo { NDDS_Transport_Plugin *plugin; int encapsulationCount; RTIEncapsulationId encapsulations[NETIO_LOCATOR_ENCAPSULATION_COUNT_MAX]; }; #define COMMEND_TRANSPORT_ENCAPSULATION_INFO_DEFAULT \ { \ NULL, /* plugin */ \ 1, /* encapsulationCount */ \ { RTI_CDR_ENCAPSULATION_ID_CDR_NATIVE, \ 0, \ 0, \ 0 }, /* encapsulations \ */ \ } struct COMMENDWriterServiceWriterProperty { /*e The type of the writer. CSTWriter is true, PSWriter otherwise */ RTIBool isCstWriter; /*e The rate to send periodic liveliness heartbeat if necessary. */ struct RTINtpTime livelinessRate; /*e transport priority */ int transportPriority; /*e What transports to use for local writer */ struct RTINetioAliasList transportAliasList; /*e Array of entryport for communication back from the reader. Max COMMEND_COMMON_APP_IPADDRESS_COUNT_MAX. */ struct RTINetioLocator entryport[COMMEND_COMMON_APP_IPADDRESS_COUNT_MAX]; /*e Number of entryports. Could be 0 if using default. Writers that do not receive anything from the reader may ignore this. */ int entryportCount; /*e Indicate whether or not to replace dropped samples with a HB * if needed to maintain liveliness */ RTIBool forceFilteredLiveliness; /*e Indicates whether the writer must be able to fragment large data if the data size exceeds the max message size of its transports. */ RTIBool supportsFragments; /*e Denotes the token bucket to use. NULL if writing synchronously. */ struct RTIEventJobDispatcherTokenBucket *tokenBucket; /*e Denotes the publishing thread to use. NULL is asynch publishing is * disabled. */ struct RTIEventJobDispatcherThread *asynchPubThread; /*e For asynch publishing flow controlling, how many bytes a single token is * allowed to send. */ RTI_INT32 bytesPerToken; /*e Max asynch samples. */ int maxAsynchSamples; /*e Indicates if batching is enabled or disabled */ RTIBool batch; /*e Session ID of this writer */ RTI_INT32 sessionId; /*e Indicates if this writer is one of multiple session-writers */ RTIBool multiSession; /* * Indicates if we should fragment for samples with a size smaller than * the minimum size of the transport MTUs minus the protocol overhead. * * This parameter is configurable with the private property: * dds.data_writer.protocol.fragment_below_transport_mtu * * The parameter was introduced to allow users to go back to the old * behavior before we fixed CORE-9287 if for some reason is needed. */ RTIBool fragmentBelowTransportMtu; /*e Indicates the publication priority of this writer, if one is assigned */ RTI_INT32 publicationPriority; /*e Indicates if dataFrag messages should be compatible with RTI DDS 43 In 43 the format of the DataFrag message was not compliant with the RTPS spec */ RTIBool use43DataFragFormat; /*e */ int transportEncapsulationInfoCount; /*e */ struct COMMENDTransportEncapsulationInfo *transportEncapsulationInfo; /* array */ /*e */ int encapsulationInfoCount; /*e */ struct RTIEncapsulationInfo *encapsulationInfo; /* array */ /* * Maximum RTPS protocol overhead for a sample. * * If this value is zero, the total RTPS overhead will be calculated on a * per sample basis considering the specific values of the sample * inlineQoS. This calculation will be done at the COMMEND layer. * * If the value is not zero, then the total RTPS overhead for a sample will * always be the one provided by this parameter. */ RTI_UINT32 maxRtpsOverhead; /*e Security behavior of the writer */ struct MIGGeneratorSecurityProperty security; /*e Indicates if UDPv4 loopback destinations should be ignored when the * associated reader is reachable through shared memory. */ RTIBool ignoreRedundantUdpv4LoopbackDestinations; /*e Indicates if UDPv6 loopback destinations should be ignored when the * associated reader is reachable through shared memory. */ RTIBool ignoreRedundantUdpv6LoopbackDestinations; /*i * All RTPS submessages from this writer will be serialized by using the * endianness defined in this field. If set to MIG_GENERATOR_ENDIAN_UNKNOWN, * the sample will be serialized using the endianness of the platform. */ MIGGeneratorEndian endianness; }; #define COMMEND_WRITER_SERVICE_WRITER_PROPERTY_DEFAULT \ { \ RTI_FALSE, /* isCstWriter */ \ RTI_NTP_TIME_MAX, /* livelinessRate */ \ NDDS_TRANSPORT_PRIORITY_DEFAULT, /* transportPriority */ \ RTI_NETIO_ALIAS_LIST_DEFAULT, /* aliasList */ \ RTI_NETIO_RTPS_LOCATOR_LIST_DEFAULT, /* entryport */ \ 0, /* entryportCount */ \ RTI_TRUE, /* forceFilteredLiveliness */ \ RTI_FALSE, /* supportsFragments */ \ NULL, /* tokenBucket */ \ NULL, /* asynchPubThread */ \ RTI_INT32_SIZE_UNLIMITED, /* bytesPerToken */ \ REDA_FAST_BUFFER_POOL_UNLIMITED, /* maxAsynchSamples */ \ RTI_FALSE, /* batch */ \ 0, /* sessionId */ \ RTI_FALSE, /* multiSession */ \ RTI_TRUE, /* fragmentBelowTransportMtu */ \ COMMEND_PUBLICATION_PRIORITY_UNDEFINED, /*publicationPriority \ */ \ RTI_FALSE, /* use43DataFragFormat */ \ 0, /* encapsulationInfoCount */ \ NULL, /* encapsulationInfo (array) */ \ 0, /* encapsulationCount */ \ NULL, /* encapsulations (array) */ \ 0, /* maxRtpsOverhead */ \ MIG_GENERATOR_SECURITY_PROPERTY_DEFAULT, /* security */ \ RTI_FALSE, /* ignoreRedundantUdpv4LoopbackDestinations */ \ RTI_FALSE, /* ignoreRedundantUdpv6LoopbackDestinations */ \ MIG_GENERATOR_ENDIAN_UNKNOWN /* endianness */ \ } struct REDAInlineList; struct COMMENDFilterSignature { int signature[4]; }; #define COMMEND_FILTER_SIGNATURE_DEFAULT \ { \ { \ 0, 0, 0, 0 \ } \ } struct COMMENDWriterServiceRemoteReaderProperty { /*e Locators that can be used to reach the remote reader. Nodes are of type COMMENDLocatorInlineNode, containing the real locator. If used as unicast locators, should be < RTPS_IP_ADDRESS_MAX. But anonymous writer may use it as unlimited number of locators. That is, if you don't treat multicast or unicast locators differently, you can mix them here. */ struct REDAInlineList *locators; /* * If this is TRUE, the locators list above only contains updated * locators and does not contain the full list of locators. This is used * by the anon writer service to only update locators that have changed. */ RTIBool locatorListContainsUpdatesOnly; /*e Some implementations make a distinction between unicast locators and the multicast locators. So when you need to make a distinction, use this list to indicate MULTICAST locators. */ struct REDAInlineList *multicastLocators; /*e Some implementations make a distinction between unicast locators and the multicast locators. So when you need to make a distinction, use this list to indicate MULTICAST locators. */ struct REDAInlineList *sessionLocators; /*e Filtering index assigned by the PRES layer. The index maps into the filter status in a sample */ int filterIndex; /*e Filter signature that is used by the user of the service * to filter samples. */ struct COMMENDFilterSignature filterSignature; /*e Indicates if the shared memory transport associated to this remote * reader is incompatible with the one of the local participant. */ RTIBool incompatibleShmemTransport; /*e * SEC-82: remote reader and remote participant interceptor handle nodes * for matched list and directed list. */ struct MIGInterceptorHandlesGroup interceptorHandles; /** * @brief The service QoS policy kind for this remote reader's Participant. * * For a description of the use case see * MIGGeneratorSample::participantServiceQosPolicyKind. */ MIGServiceQosPolicyKind participantServiceQosPolicyKind; }; /* clang-format off */ #define COMMEND_WRITER_SERVICE_REMOTE_READER_PROPERTY_DEFAULT \ { \ NULL, /* locators */ \ RTI_FALSE, /* locatorListContainsUpdatesOnly */ \ NULL, /* multicastLocators */ \ NULL, /* sessionLocators */ \ COMMEND_FILTER_INDEX_INVALID, /* filterIndex */ \ COMMEND_FILTER_SIGNATURE_DEFAULT, /* filterSignature */ \ RTI_FALSE, /* incompatibleShmemTransport */ \ MIGInterceptorHandlesGroup_INITIALIZER, /* interceptorHandles */ \ MIG_UNKNOWN_SERVICE_QOS /* participantServiceQosPolicyKind */ \ } /* clang-format on */ /*e \ingroup COMMENDWriterServiceModule * Send/Push an issue. * * @param me \b In. * @param firstUnackedSn \b Out. (Cannot be NULL for SR) Only if the first * unacked sn has been changed before/after write(), it will be set to the new * value. * @param writer \b In. * @param firstSn \b In. * @param sample \b InOut. * @param nowIn NOT the source_timestamp; the local time when this write is * being performed * @param blockTime the max amount of time the write operation can take. derived * from maxBlockingTime less the amount spent by upper layers * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool (*COMMENDWriterServiceWriteFunction)( struct COMMENDWriterService *me, struct REDASequenceNumber *firstUnackedSnOut, const struct REDAWeakReference *writer, const struct REDASequenceNumber *firstSn, const struct REDASequenceNumber *firstVirtualSn, struct MIGGeneratorSample *sample, const struct RTINtpTime *nowIn, const struct RTINtpTime *blockTime, struct COMMENDFilterStatus *filterStatus, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Assert liveliness heartbeat. * * @param me \b In. * @param writer \b In. * @param data \b In. * @param sn \b In. * @param now \b In. Can be NULL. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool (*COMMENDWriterServiceLivelinessAssertFunction)( struct COMMENDWriterService *me, const struct REDAWeakReference *writer, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Add a new writer. * * The parameter firstSn, lastSn and lastUnackSn are used * when the commend writers are created with a restored queue. * * @pre Valid pointers. No writer with same oid added before. * @post On success (RTI_TRUE is returned): a new writer entry is added. * * @param me \b In. * @param recordWROut \b Out. The weak reference to the writer entry. * * @param oid \b In. The writer's object id. * @param listener \b In. * @param storage \b In. * @param property \b In. * @param firstSn \b In. First available sequence number. If NULL * (0,1) will be used. * @param lastSn \b In. Last available sequence number. If NULL * (0,0) will be used. * @param lastUnackSn \b In. Last unack sequence numnber. If NULL * (0,1) will be used * @param ea \b In. * @param worker \b In. * * @return RTI_TRUE if success */ typedef RTIBool (*COMMENDWriterServiceWriterCreateFunction)( struct COMMENDWriterService *me, struct REDAWeakReference *recordWROut, MIGRtpsObjectId oid, const struct COMMENDWriterServiceWriterSampleListener *sListener, const struct COMMENDWriterServiceWriterActivityListener *aListener, const struct COMMENDWriterServiceWriterStatusListener *statusListener, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct COMMENDWriterServiceWriterProperty *property, const struct REDASequenceNumber *firstSn, const struct REDASequenceNumber *lastSn, const struct REDASequenceNumber *firstVirtualSn, const struct REDASequenceNumber *lastVirtualSn, const struct REDASequenceNumber *lowestUnackSn, struct REDAExclusiveArea *ea, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * * Modify the property of the writer. * * @pre Valid pointers. * @post On success (RTI_TRUE is returned): the writer property is changed. * * @param me \b In. * @param writerWR \b In. The weak reference to the writer entry. * @param property \b In. * @param worker \b In. * * @return RTI_TRUE if success */ typedef RTIBool (*COMMENDWriterServiceWriterPropertySetFunction)( struct COMMENDWriterService *me, struct REDAWeakReference *writerWR, const struct COMMENDWriterServiceWriterProperty *property, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Assert a remote reader group. * All remote readers in the same group share a common destination (usually * a multicast address). Data send/resend will via the group, rather than * individual remote reader. * A group is identified by the writerWR and the destinationGroup. * * @param me \b In. * @param groupWR \b Out. The weak reference to the group entry. * @param writerWR \b In. The writer's weak reference to which the group * belongs to. * @param multicastLocator \b In. Destination shared by the whole group. * @param worker \b In. * @return RTI_TRUE if success. */ typedef RTIBool (*COMMENDWriterServiceGroupAssertFunction)( struct COMMENDWriterService *me, struct REDAWeakReference *recordWR, struct REDAWeakReference *writer, const struct RTINetioLocator *multicastLocator, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Assert or modify a remote reader. * * When modifying an existing remote reader, all immutable parameters will * be ignored (i.e., use NULL in this case is fine). It's caller's * reponsibility to make sure those parameters are the same as the ones * used when first assert the remote writer. Here, only certain fields in * property are mutable. Refer to specific property for what fields are * mutable. * * @param me \b In. * @param reader \b Out. The weak reference to the commend reader asserted. * @param readerAlreadyExisted \b Out. Flag to indicate if the commend reader * already existed. * @param writer \b In. The weak reference to the writer associated with the * remote reader. * @param group \b In. The weak reference to the group associated with the * remote reader. NULL or INVALID if the remote reader doesn't have any group. * @param property \b In. Pointer to the property of the remote reader. If a * remote reader with the guid has been asserted before, the immutable parts of * the property will be ignored, and so those parts can be set to any value. * @param worker \b In. * * @return RTI_TRUE if success. */ typedef RTIBool (*COMMENDWriterServiceRemoteReaderAssertFunction)( struct COMMENDWriterService *me, struct REDAWeakReference *reader, RTIBool *readerAlreadyExisted, const struct REDAWeakReference *writer, const struct REDAWeakReference *group, const struct MIGRtpsGuid *guid, const struct MIGRtpsGuid *virtualGuid, const RTIBool isDurSubReader, const struct COMMENDWriterServiceWriterListenerStorage *storage, const struct COMMENDWriterServiceRemoteReaderProperty *property, struct REDAWorker *worker); typedef RTIBool (*COMMENDWriterServiceWriterDestroyFunction)( struct COMMENDWriterService *w, MIGRtpsObjectId oid, struct REDAWorker *worker); typedef RTIBool (*COMMENDWriterServiceGroupRemoveFunction)( struct COMMENDWriterService *me, struct REDAWeakReference *group, struct REDAWorker *worker); typedef RTIBool (*COMMENDWriterServiceRemoteReaderRemoveFunction)( struct COMMENDWriterService *w, MIGRtpsObjectId oid, const struct MIGRtpsGuid *guid, struct REDAWorker *worker); /* * Notify the state (i.e. first sn and last sn) change. */ typedef RTIBool (*COMMENDWriterServiceStateChangedFunction)( struct COMMENDWriterService *w, const struct REDAWeakReference *writer, const struct REDASequenceNumber *firstSn, const struct REDASequenceNumber *lastSn, const struct REDASequenceNumber *firstVirtualSn, const struct REDASequenceNumber *lastVirtualSn, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * This structure represents the service. The service is defined by the * functions in this structure. * Derive from this structure and set the pointers to define a service. * * Shutdown the writer service. It should be done before the active facade * shutdown. */ typedef void (*COMMENDWriterServiceShutdownFunction)( struct COMMENDWriterService *w, struct REDAWorker *worker); typedef void (*COMMENDWriterServiceDeletionFunction)( struct COMMENDWriterService *w, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Get statistics of the local COMMEND writer. */ typedef RTIBool (*COMMENDWriterServiceGetLocalWriterStatisticsFunction)( struct COMMENDWriterService *w, struct COMMENDWriterServiceLocalWriterStatistics *stats, const struct REDAWeakReference *writer, RTIBool clearChange, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Get statistics of communications between local writer and matched remote * reader identified by guid */ typedef RTIBool (*COMMENDWriterServiceGetMatchedSubscriptionStatisticsFunction)( struct COMMENDWriterService *w, struct COMMENDWriterServiceMatchedReaderStatistics *status, const struct MIGRtpsGuid *guid, const struct REDAWeakReference *writer, RTIBool clearChange, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Get statistics of communications between local writer and matched remote * reader identified by locator */ typedef RTIBool ( *COMMENDWriterServiceGetMatchedSubscriptionStatisticsByLocatorFunction)( struct COMMENDWriterService *w, struct COMMENDWriterServiceMatchedDestinationStatistics *status, const struct RTINetioLocator *locator, const struct REDAWeakReference *writer, RTIBool clearChange, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Set statistics of the local COMMEND writer. */ typedef RTIBool (*COMMENDWriterServiceSetLocalWriterStatisticsFunction)( struct COMMENDWriterService *w, const struct COMMENDWriterServiceLocalWriterStatistics *stats, const struct REDAWeakReference *writer, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Set statistics of communications between local writer and matched remote * reader identified by guid */ typedef RTIBool (*COMMENDWriterServiceSetMatchedSubscriptionStatisticsFunction)( struct COMMENDWriterService *w, const struct COMMENDWriterServiceMatchedReaderStatistics *status, const struct MIGRtpsGuid *guid, const struct REDAWeakReference *writer, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Set statistics of communications between local writer and matched remote * reader identified by locator */ typedef RTIBool ( *COMMENDWriterServiceSetMatchedSubscriptionStatisticsByLocatorFunction)( struct COMMENDWriterService *w, const struct COMMENDWriterServiceMatchedDestinationStatistics *status, const struct RTINetioLocator *locator, const struct REDAWeakReference *writer, struct REDAWorker *worker); /*e \ingroup COMMENDWriterServiceModule * Fills out the number of matching destinations, and fills out matchedLocators * if not null. * * @param me \b In. * @param matchedLocatorCount \b Out. * @param matchedLocators \b Out. * @param writer \b In. * @param worker \b In. */ typedef RTIBool (*COMMENDWriterServiceGetMatchedDestinations)( struct COMMENDWriterService *w, RTI_INT32 *matchedLocatorCount, struct RTINetioLocator *matchedLocators, const struct REDAWeakReference *writer, struct REDAWorker *worker); typedef RTIBool (*COMMENDWriterServiceInvalidateRemoteReaderFilterFunction)( struct COMMENDWriterService *w, MIGRtpsObjectId oid, const struct MIGRtpsGuid *guid, struct REDAWorker *worker); struct COMMENDWriterService { /*e */ COMMENDWriterServiceWriterCreateFunction createWriter; /*e */ COMMENDWriterServiceWriterPropertySetFunction setWriterProperty; /*e */ COMMENDWriterServiceWriterDestroyFunction destroyWriter; /*e */ COMMENDWriterServiceRemoteReaderAssertFunction assertRemoteReader; /*e */ COMMENDWriterServiceRemoteReaderRemoveFunction removeRemoteReader; /*e */ COMMENDWriterServiceInvalidateRemoteReaderFilterFunction invalidateRemoteReaderFilter; /*e */ COMMENDWriterServiceWriteFunction write; /*e */ COMMENDWriterServiceStateChangedFunction stateChanged; COMMENDWriterServiceLivelinessAssertFunction assertLiveliness; COMMENDWriterServiceShutdownFunction shutdown; COMMENDWriterServiceDeletionFunction deleteService; COMMENDWriterServiceGetMatchedDestinations getMatchedDestinations; COMMENDWriterServiceGetLocalWriterStatisticsFunction getLocalWriterStatistics; COMMENDWriterServiceGetMatchedSubscriptionStatisticsFunction getMatchedSubscriptionStatistics; COMMENDWriterServiceGetMatchedSubscriptionStatisticsByLocatorFunction getMatchedSubscriptionStatisticsByLocator; COMMENDWriterServiceSetLocalWriterStatisticsFunction setLocalWriterStatistics; COMMENDWriterServiceSetMatchedSubscriptionStatisticsFunction setMatchedSubscriptionStatistics; COMMENDWriterServiceSetMatchedSubscriptionStatisticsByLocatorFunction setMatchedSubscriptionStatisticsByLocator; /* * pool of transport plugins used for resolving encapsulations of * TransportEncapsulationSettings. Allocated when creating the first * writer. Subsequent writers use this same pool as long as they have * at most the same number of transports as the first writer. */ struct REDAFastBufferPool *transportPluginPool; }; #ifdef __cplusplus } /* extern "C" */ #endif #include "commend/commend_writerService_impl.h" #endif /* commend_writerService_h */