@@ -403,6 +403,69 @@ typedef BML_Result (*PFN_BML_ImcGetTopicName)(BML_Context ctx,
403403 size_t buffer_size ,
404404 size_t * out_length );
405405
406+ /* ========================================================================
407+ * Message Flow Monitoring APIs
408+ * ======================================================================== */
409+
410+ /**
411+ * @brief Trace record for a published message.
412+ *
413+ * Captures metadata about a message at publish time for flow monitoring.
414+ */
415+ typedef struct BML_ImcMessageTrace {
416+ size_t struct_size ; /**< sizeof(BML_ImcMessageTrace), must be first */
417+ BML_TopicId topic ; /**< Topic ID */
418+ BML_Mod owner ; /**< Publishing module */
419+ uint64_t timestamp_qpc ; /**< QueryPerformanceCounter timestamp */
420+ size_t payload_size ; /**< Size of payload in bytes */
421+ uint32_t payload_type_id ; /**< Payload type ID */
422+ uint32_t priority ; /**< Message priority */
423+ uint32_t flags ; /**< Message flags */
424+ } BML_ImcMessageTrace ;
425+
426+ /**
427+ * @brief Callback invoked when a message is published.
428+ *
429+ * Fired from owner-variant publish methods (Publish/PublishEx/PublishBuffer/
430+ * PublishInterceptable/PublishState) after validation but before dispatch.
431+ * Not invoked for internal publishes or non-owner variants.
432+ *
433+ * @param[in] trace Trace record with message metadata
434+ * @param[in] user_data Opaque pointer provided at registration
435+ *
436+ * @threadsafe Yes (invoked from publish path)
437+ * @warning Must be fast and non-blocking. Do not call IMC Pump from tap.
438+ */
439+ typedef void (* BML_ImcMessageTap )(const BML_ImcMessageTrace * trace , void * user_data );
440+
441+ /**
442+ * @brief Register a message tap for flow monitoring.
443+ *
444+ * Only one tap can be active at a time. Overwrites any previous tap.
445+ * Use for DevTools, debuggers, or telemetry systems.
446+ *
447+ * @param[in] owner Module handle (owner of tap)
448+ * @param[in] tap Tap callback (NULL to unregister)
449+ * @param[in] user_data Opaque pointer passed to tap
450+ * @return BML_RESULT_OK on success
451+ *
452+ * @threadsafe Yes
453+ */
454+ typedef BML_Result (* PFN_BML_ImcRegisterMessageTap )(BML_Mod owner ,
455+ BML_ImcMessageTap tap ,
456+ void * user_data );
457+
458+ /**
459+ * @brief Unregister the current message tap.
460+ *
461+ * @param[in] owner Module handle (must match registration owner)
462+ * @return BML_RESULT_OK on success
463+ * @return BML_RESULT_NOT_FOUND if no tap registered or owner mismatch
464+ *
465+ * @threadsafe Yes
466+ */
467+ typedef BML_Result (* PFN_BML_ImcUnregisterMessageTap )(BML_Mod owner );
468+
406469/* ========================================================================
407470 * Bus Interface Vtable
408471 * ======================================================================== */
@@ -431,6 +494,8 @@ typedef struct BML_ImcBusInterface {
431494 PFN_BML_ImcResetStats ResetStats ;
432495 PFN_BML_ImcGetTopicInfo GetTopicInfo ;
433496 PFN_BML_ImcGetTopicName GetTopicName ;
497+ PFN_BML_ImcRegisterMessageTap RegisterMessageTap ;
498+ PFN_BML_ImcUnregisterMessageTap UnregisterMessageTap ;
434499} BML_ImcBusInterface ;
435500
436501BML_END_CDECLS
0 commit comments