Пример #1
0
DDS_QueryCondition createQueryCondition(DDS_DataReader dataReader, DDS_char *query_string, DDS_char* queryParameter)
{
   DDS_StringSeq* query_parameters = DDS_StringSeq__alloc();
   DDS_QueryCondition queryCondition;

   query_parameters->_length = 1;
   query_parameters->_maximum = 1;
   query_parameters->_release = TRUE;
   query_parameters->_buffer = DDS_StringSeq_allocbuf (1);
   checkHandle(query_parameters->_buffer, "DDS_StringSeq_allocbuf");
   query_parameters->_buffer[0] = DDS_string_dup (queryParameter);
   checkHandle(query_parameters->_buffer[0], "DDS_string_dup");

   queryCondition = DDS_DataReader_create_querycondition(dataReader,
            DDS_ANY_SAMPLE_STATE,
            DDS_ANY_VIEW_STATE,
            DDS_ANY_INSTANCE_STATE,
            query_string,
            query_parameters);
   checkHandle(queryCondition, "DDS_DataReader_create_querycondition");

   DDS_free(query_parameters);

   return queryCondition;
}
int main(int argc, char *argv[])
{
   char* partition_name = "ContentFilteredTopic example";
   DDS_Subscriber contentFilteredTopicDataSubscriber;
   DDS_DataReader contentFilteredTopicDataDataReader;
   ContentFilteredTopicData_Stock* contentFilteredTopicDataSample;
   DDS_InstanceHandle_t userHandle;
   DDS_sequence_ContentFilteredTopicData_Stock* msgList = DDS_sequence_ContentFilteredTopicData_Stock__alloc();
   DDS_SampleInfoSeq* infoSeq = DDS_SampleInfoSeq__alloc();
   c_bool isClosed = FALSE;
   unsigned long j, userInput, timeOut;
   const char *filterValueToSubscribe;
   DDS_char* contentFilteredStockTopicName = "MyStockTopic";
   DDS_ContentFilteredTopic contentFilteredTopic;
   int filter_expressionLength;
   const char* filter_expressionPrefix = "ticker = '";
   const char* filter_expressionSuffix = "'";
   DDS_char *filter_expression;
   const DDS_StringSeq* filter_parameters = DDS_StringSeq__alloc();
   os_time delay_200ms = { 0, 200000000 };
   int count = 0;

   // usage : ContentFilteredTopicDataSubscriber <topic's content filtering string>
   if( argc < 2 )
   {
      usage();
   }
   printf("=== ContentFilteredTopicDataSubscriber");
   // Removed to comply with expected results
   //printf("\n\n Parameter is \"%s\"", argv[1]);
   filterValueToSubscribe = argv[1];

   createParticipant( partition_name );

   // Register Stock Topic's type in the DDS Domain.
   g_StockTypeSupport = (DDS_TypeSupport) ContentFilteredTopicData_StockTypeSupport__alloc();
   checkHandle(g_StockTypeSupport, "ContentFilteredTopicData_StockTypeSupport__alloc");
   registerStockType(g_StockTypeSupport);
   // Create Stock Topic in the DDS Domain.
   g_StockTypeName = (char*) ContentFilteredTopicData_StockTypeSupport_get_type_name(g_StockTypeSupport);
   g_StockTopic = createTopic("StockTrackerExclusive", g_StockTypeName);
   DDS_free(g_StockTypeName);
   DDS_free(g_StockTypeSupport);

   // Create the Subscriber's in the DDS Domain.
   contentFilteredTopicDataSubscriber = createSubscriber();

   // create subscription filter

   filter_expressionLength = strlen(filter_expressionPrefix);
   filter_expressionLength += strlen(filterValueToSubscribe);
   filter_expressionLength += strlen(filter_expressionSuffix);
   filter_expression = DDS_string_alloc(filter_expressionLength);
   snprintf(filter_expression, filter_expressionLength + 1, "%s%s%s", filter_expressionPrefix, filterValueToSubscribe, filter_expressionSuffix);

   // create ContentFilteredTopic to retrieve only the samples with the given Stock.
   contentFilteredTopic = createContentFilteredTopic(contentFilteredStockTopicName, g_StockTopic, filter_expression, filter_parameters);
   // create Filtered DataReader

   printf( "\n=== [ContentFilteredTopicDataSubscriber] Subscription filter : %s", filter_expression );

   // Request a Reader from the the Subscriber.
   contentFilteredTopicDataDataReader = createContentFilteredDataReader(contentFilteredTopicDataSubscriber, contentFilteredTopic);

   printf( "\n=== [ContentFilteredTopicDataSubscriber] Ready ..." );

   do
   {
      g_status = ContentFilteredTopicData_StockDataReader_take(contentFilteredTopicDataDataReader, msgList, infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
      checkStatus(g_status, "ContentFilteredTopicData_StockDataReaderView_take");
      if( msgList->_length > 0 )
      {
         j = 0;
         do
         {
            contentFilteredTopicDataSample = &msgList->_buffer[j];            
            if( infoSeq->_buffer[j].valid_data )
            {
               if( contentFilteredTopicDataSample->price != (DDS_float) -1.0f )
               {
            	   int floatWidth = ( ((DDS_float) contentFilteredTopicDataSample->price) - ((long) contentFilteredTopicDataSample->price) ) ? 1 : 0;
                   printf("\n=== [ContentFilteredTopicDataSubscriber] receives stockQuote :  (%s, %.*f)", contentFilteredTopicDataSample->ticker, floatWidth, contentFilteredTopicDataSample->price);
               }
               else
               {            	   
                  isClosed = TRUE;
               }
            }
         }
         while( ++j < msgList->_length );

         g_status = ContentFilteredTopicData_StockDataReader_return_loan(contentFilteredTopicDataDataReader, msgList, infoSeq);
         checkStatus(g_status, "ContentFilteredTopicData_StockDataReader_return_loan");

         if(isClosed == FALSE)
         {
            os_nanoSleep(delay_200ms);
            ++count;
         }
      }
   }
   while( isClosed == FALSE && count < 1500); // We dont want the example to run indefinitely

   printf("\n=== [ContentFilteredTopicDataSubscriber] Market Closed\n");

   // Cleanup DDS from the created Entities.
   deleteDataReader(contentFilteredTopicDataSubscriber, contentFilteredTopicDataDataReader);
   deleteSubscriber(contentFilteredTopicDataSubscriber);
   deleteContentFilteredTopic(contentFilteredTopic);
   deleteTopic(g_StockTopic);
   deleteParticipant();

   // Cleanup C allocations,
   // recursively freeing the allocated structures and sequences using the OpenSplice API.
   DDS__free(msgList);
   DDS__free(infoSeq);

   // Print out an empty line, just to let behind a clean new line for the shell..
   // Removed to comply with expected results
   //printf("\n\r");
   return 0;
}
Пример #3
0
int
main (
    int argc,
    char *argv[])
{
    /* Generic DDS entities */
    DDS_DomainParticipantFactory    dpf;
    DDS_DomainParticipant           participant;
    DDS_Topic                       chatMessageTopic;
    DDS_Topic                       nameServiceTopic;
    DDS_MultiTopic                  namedMessageTopic;
    DDS_Subscriber                  chatSubscriber;

    /* Type-specific DDS entities */
    Chat_ChatMessageTypeSupport     chatMessageTS;
    Chat_NameServiceTypeSupport     nameServiceTS;
    Chat_NamedMessageTypeSupport    namedMessageTS;
    Chat_NamedMessageDataReader     chatAdmin;
    DDS_sequence_Chat_NamedMessage  *msgSeq;
    DDS_SampleInfoSeq               *infoSeq;

    /* QosPolicy holders */
    DDS_TopicQos                    *reliable_topic_qos;
    DDS_TopicQos                    *setting_topic_qos;
    DDS_SubscriberQos               *sub_qos;
    DDS_StringSeq                   *parameterList;

    /* DDS Identifiers */
    DDS_DomainId_t                  domain = NULL;
    DDS_ReturnCode_t                status;

    /* Others */
    DDS_unsigned_long               i;
    DDS_boolean                     terminated = FALSE;
    char *                          partitionName;
    char *                          chatMessageTypeName = NULL;
    char *                          nameServiceTypeName = NULL;
    char *                          namedMessageTypeName = NULL;
    
    /* Options: MessageBoard [ownID] */
    /* Messages having owner ownID will be ignored */
    parameterList = DDS_StringSeq__alloc();
    checkHandle(parameterList, "DDS_StringSeq__alloc");
    parameterList->_length = 1;
    parameterList->_maximum = 1;
    parameterList->_buffer = DDS_StringSeq_allocbuf(1);
    checkHandle(parameterList->_buffer, "DDS_StringSeq_allocbuf");
    
    if (argc > 1) {
        parameterList->_buffer[0] = DDS_string_alloc ( strlen(argv[1]) );
        checkHandle(parameterList->_buffer[0], "DDS_string_alloc");
        strcpy (parameterList->_buffer[0], argv[1]);
    }
    else
    {
        parameterList->_buffer[0] = DDS_string_alloc(1);
        checkHandle(parameterList->_buffer[0], "DDS_string_alloc");
        strcpy (parameterList->_buffer[0], "0");
    }
      
    /* Create a DomainParticipantFactory and a DomainParticipant (using Default QoS settings. */
    dpf = DDS_DomainParticipantFactory_get_instance ();
    checkHandle(dpf, "DDS_DomainParticipantFactory_get_instance");
    participant = DDS_DomainParticipantFactory_create_participant (
        dpf, 
        domain, 
        DDS_PARTICIPANT_QOS_DEFAULT, 
        NULL, 
        DDS_STATUS_MASK_NONE);
    checkHandle(participant, "DDS_DomainParticipantFactory_create_participant");  

    /* Register the required datatype for ChatMessage. */
    chatMessageTS = Chat_ChatMessageTypeSupport__alloc();
    checkHandle(chatMessageTS, "Chat_ChatMessageTypeSupport__alloc");
    chatMessageTypeName = Chat_ChatMessageTypeSupport_get_type_name(chatMessageTS);
    status = Chat_ChatMessageTypeSupport_register_type(
        chatMessageTS, 
        participant, 
        chatMessageTypeName);
    checkStatus(status, "Chat_ChatMessageTypeSupport_register_type");
    
    /* Register the required datatype for NameService. */
    nameServiceTS = Chat_NameServiceTypeSupport__alloc();
    checkHandle(nameServiceTS, "Chat_NameServiceTypeSupport__alloc");
    nameServiceTypeName = Chat_NameServiceTypeSupport_get_type_name(nameServiceTS);
    status = Chat_NameServiceTypeSupport_register_type(
        nameServiceTS, 
        participant, 
        nameServiceTypeName);
    checkStatus(status, "Chat_NameServiceTypeSupport_register_type");
    
    /* Register the required datatype for NamedMessage. */
    namedMessageTS = Chat_NamedMessageTypeSupport__alloc();
    checkHandle(namedMessageTS, "Chat_NamedMessageTypeSupport__alloc");
    namedMessageTypeName = Chat_NamedMessageTypeSupport_get_type_name(namedMessageTS);
    status = Chat_NamedMessageTypeSupport_register_type(
        namedMessageTS, 
        participant, 
        namedMessageTypeName);
    checkStatus(status, "Chat_NamedMessageTypeSupport_register_type");
    
    /* Set the ReliabilityQosPolicy to RELIABLE. */
    reliable_topic_qos = DDS_TopicQos__alloc();
    checkHandle(reliable_topic_qos, "DDS_TopicQos__alloc");
    status = DDS_DomainParticipant_get_default_topic_qos(participant, reliable_topic_qos);
    checkStatus(status, "DDS_DomainParticipant_get_default_topic_qos");
    reliable_topic_qos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
    
    /* Make the tailored QoS the new default. */
    status = DDS_DomainParticipant_set_default_topic_qos(participant, reliable_topic_qos);
    checkStatus(status, "DDS_DomainParticipant_set_default_topic_qos");

    /* Use the changed policy when defining the ChatMessage topic */
    chatMessageTopic = DDS_DomainParticipant_create_topic( 
        participant, 
        "Chat_ChatMessage", 
        chatMessageTypeName, 
        reliable_topic_qos, 
        NULL, 
        DDS_STATUS_MASK_NONE);
    checkHandle(chatMessageTopic, "DDS_DomainParticipant_create_topic (ChatMessage)");
    
    /* Set the DurabilityQosPolicy to TRANSIENT. */
    setting_topic_qos = DDS_TopicQos__alloc();
    checkHandle(setting_topic_qos, "DDS_TopicQos__alloc");
    status = DDS_DomainParticipant_get_default_topic_qos(participant, setting_topic_qos);
    checkStatus(status, "DDS_DomainParticipant_get_default_topic_qos");
    setting_topic_qos->durability.kind = DDS_TRANSIENT_DURABILITY_QOS;

    /* Create the NameService Topic. */
    nameServiceTopic = DDS_DomainParticipant_create_topic( 
        participant, 
        "Chat_NameService", 
        nameServiceTypeName, 
        setting_topic_qos, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(nameServiceTopic, "DDS_DomainParticipant_create_topic");
    
    /* Create a multitopic that substitutes the userID with its corresponding userName. */
    namedMessageTopic = DDS_DomainParticipant_create_simulated_multitopic(
        participant, 
        "Chat_NamedMessage", 
        namedMessageTypeName, 
        "SELECT userID, name AS userName, index, content "
            "FROM Chat_NameService NATURAL JOIN Chat_ChatMessage WHERE userID <> %0",
        parameterList);
    checkHandle(namedMessageTopic, "DDS_DomainParticipant_simulate_multitopic");

    /* Adapt the default SubscriberQos to read from the "ChatRoom" Partition. */
    partitionName = "ChatRoom";
    sub_qos = DDS_SubscriberQos__alloc();
    checkHandle(sub_qos, "DDS_SubscriberQos__alloc");
    status = DDS_DomainParticipant_get_default_subscriber_qos (participant, sub_qos);
    checkStatus(status, "DDS_DomainParticipant_get_default_subscriber_qos");
    sub_qos->partition.name._length = 1;
    sub_qos->partition.name._maximum = 1;
    sub_qos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    checkHandle(sub_qos->partition.name._buffer, "DDS_StringSeq_allocbuf");
    sub_qos->partition.name._buffer[0] = DDS_string_alloc ( strlen(partitionName) );
    checkHandle(sub_qos->partition.name._buffer[0], "DDS_string_alloc");
    strcpy (sub_qos->partition.name._buffer[0], partitionName);

    /* Create a Subscriber for the MessageBoard application. */
    chatSubscriber = DDS_DomainParticipant_create_subscriber(participant, sub_qos, NULL, DDS_STATUS_MASK_NONE);
    checkHandle(chatSubscriber, "DDS_DomainParticipant_create_subscriber");
    
    /* Create a DataReader for the NamedMessage Topic (using the appropriate QoS). */
    chatAdmin = DDS_Subscriber_create_datareader( 
        chatSubscriber, 
        namedMessageTopic, 
        DDS_DATAREADER_QOS_USE_TOPIC_QOS, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(chatAdmin, "DDS_Subscriber_create_datareader");
    
    /* Print a message that the MessageBoard has opened. */
    printf("MessageBoard has opened: send a ChatMessage with userID = -1 to close it....\n\n");

    /* Allocate the sequence holders for the DataReader */
    msgSeq = DDS_sequence_Chat_NamedMessage__alloc();
    checkHandle(msgSeq, "DDS_sequence_Chat_NamedMessage__alloc");
    infoSeq = DDS_SampleInfoSeq__alloc();
    checkHandle(infoSeq, "DDS_SampleInfoSeq__alloc");

    while (!terminated) {
        /* Note: using read does not remove the samples from 
           unregistered instances from the DataReader. This means 
           that the DataRase would use more and more resources. 
           That's why we use take here instead. */

        status = Chat_NamedMessageDataReader_take( 
            chatAdmin, 
            msgSeq, 
            infoSeq, 
            DDS_LENGTH_UNLIMITED, 
            DDS_ANY_SAMPLE_STATE, 
            DDS_ANY_VIEW_STATE, 
            DDS_ALIVE_INSTANCE_STATE );
        checkStatus(status, "Chat_NamedMessageDataReader_take");

        for (i = 0; i < msgSeq->_length; i++) {
            Chat_NamedMessage *msg = &(msgSeq->_buffer[i]);
            if (msg->userID == TERMINATION_MESSAGE) {
                printf("Termination message received: exiting...\n");
                terminated = TRUE;
            } else {
                printf ("%s: %s\n", msg->userName, msg->content);
            }
        }

        status = Chat_NamedMessageDataReader_return_loan(chatAdmin, msgSeq, infoSeq);
        checkStatus(status, "Chat_ChatMessageDataReader_return_loan");
        
        /* Sleep for some amount of time, as not to consume too much CPU cycles. */
        Sleep(100);
    }

    /* Remove the DataReader */
    status = DDS_Subscriber_delete_datareader(chatSubscriber, chatAdmin);
    checkStatus(status, "DDS_Subscriber_delete_datareader");
    
    /* Remove the Subscriber. */
    status = DDS_DomainParticipant_delete_subscriber(participant, chatSubscriber);
    checkStatus(status, "DDS_DomainParticipant_delete_subscriber");
    
    /* Remove the Topics. */
    status = DDS_DomainParticipant_delete_simulated_multitopic(participant, namedMessageTopic);
    checkStatus(status, "DDS_DomainParticipant_delete_simulated_multitopic");
    
    status = DDS_DomainParticipant_delete_topic(participant, nameServiceTopic);
    checkStatus(status, "DDS_DomainParticipant_delete_topic (nameServiceTopic)");
    
    status = DDS_DomainParticipant_delete_topic(participant, chatMessageTopic);
    checkStatus(status, "DDS_DomainParticipant_delete_topic (chatMessageTopic)");
    
    /* De-allocate the QoS policies. */
    DDS_free(reliable_topic_qos);
    DDS_free(setting_topic_qos);
    DDS_free(sub_qos);  // Note that DDS_free recursively de-allocates all indirections as well!!

    /* De-allocate the type-names and TypeSupport objects. */
    DDS_free(namedMessageTypeName);
    DDS_free(nameServiceTypeName);
    DDS_free(chatMessageTypeName);
    DDS_free(namedMessageTS);
    DDS_free(nameServiceTS);
    DDS_free(chatMessageTS);
    
    /* Remove the DomainParticipant. */
    status = DDS_DomainParticipantFactory_delete_participant(dpf, participant);
    checkStatus(status, "DDS_DomainParticipantFactory_delete_participant");

    return 0;
}
Пример #4
0
DDS_MultiTopic
DDS_DomainParticipant_create_simulated_multitopic (
    DDS_DomainParticipant participant,
    const DDS_char *name,
    const DDS_char *type_name,
    const DDS_char *subscription_expression,
    const DDS_StringSeq *expression_parameters )
{
    /* Type-specific DDS entities */
    static Chat_ChatMessageDataReader       chatMessageDR;
    static Chat_NameServiceDataReader       nameServiceDR;
    static Chat_NamedMessageDataWriter      namedMessageDW;
    
    /* Query related stuff */
    static DDS_QueryCondition               nameFinder;
    static DDS_StringSeq                    *nameFinderParams;
    
    /* QosPolicy holders */
    DDS_TopicQos                    *namedMessageQos;
    DDS_SubscriberQos               *sub_qos;    
    DDS_PublisherQos                *pub_qos;

    /* Others */
    const char                      *partitionName = "ChatRoom";
    const char                      *nameFinderExpr;
    struct MsgListenerState         *listener_state;
    DDS_Duration_t                  infiniteTimeOut  = DDS_DURATION_INFINITE;
    DDS_ReturnCode_t                status;

    /* Lookup both components that constitute the multi-topic. */
    chatMessageTopic = DDS_DomainParticipant_find_topic(
        participant, 
        "Chat_ChatMessage", 
        &infiniteTimeOut);
    checkHandle(chatMessageTopic, "DDS_DomainParticipant_find_topic (Chat_ChatMessage)");

    nameServiceTopic = DDS_DomainParticipant_find_topic(
        participant, 
        "Chat_NameService", 
        &infiniteTimeOut);
    checkHandle(nameServiceTopic, "DDS_DomainParticipant_find_topic (Chat_NameService)");

    /* Create a ContentFilteredTopic to filter out our own ChatMessages. */
    filteredMessageTopic = DDS_DomainParticipant_create_contentfilteredtopic(
        participant, 
        "Chat_FilteredMessage", 
        chatMessageTopic,
        "userID <> %0",
        expression_parameters);
    checkHandle(filteredMessageTopic, "DDS_DomainParticipant_create_contentfilteredtopic");
        

    /* Adapt the default SubscriberQos to read from the "ChatRoom" Partition. */
    sub_qos = DDS_SubscriberQos__alloc();
    checkHandle(sub_qos, "DDS_SubscriberQos__alloc");
    status = DDS_DomainParticipant_get_default_subscriber_qos (participant, sub_qos);
    checkStatus(status, "DDS_DomainParticipant_get_default_subscriber_qos");
    sub_qos->partition.name._length = 1;
    sub_qos->partition.name._maximum = 1;
    sub_qos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    checkHandle(sub_qos->partition.name._buffer, "DDS_StringSeq_allocbuf");
    sub_qos->partition.name._buffer[0] = DDS_string_alloc ( strlen(partitionName) );
    checkHandle(sub_qos->partition.name._buffer[0], "DDS_string_alloc");
    strcpy (sub_qos->partition.name._buffer[0], partitionName);

    /* Create a private Subscriber for the multitopic simulator. */
    multiSub = DDS_DomainParticipant_create_subscriber(participant, sub_qos, NULL, DDS_STATUS_MASK_NONE);
    checkHandle(multiSub, "DDS_DomainParticipant_create_subscriber (for multitopic)");
    
    /* Create a DataReader for the FilteredMessage Topic (using the appropriate QoS). */
    chatMessageDR = DDS_Subscriber_create_datareader( 
        multiSub, 
        filteredMessageTopic, 
        DDS_DATAREADER_QOS_USE_TOPIC_QOS, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(chatMessageDR, "DDS_Subscriber_create_datareader (ChatMessage)");
    
    /* Create a DataReader for the nameService Topic (using the appropriate QoS). */
    nameServiceDR = DDS_Subscriber_create_datareader( 
        multiSub, 
        nameServiceTopic, 
        DDS_DATAREADER_QOS_USE_TOPIC_QOS, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(nameServiceDR, "DDS_Subscriber_create_datareader (NameService)");
    
    /* Define the SQL expression (using a parameterized value). */
    nameFinderExpr = "userID = %0";
    
    /* Allocate and assign the query parameters. */
    nameFinderParams = DDS_StringSeq__alloc();
    checkHandle(nameFinderParams, "DDS_StringSeq__alloc");
    nameFinderParams->_length = 1;
    nameFinderParams->_maximum = 1;
    nameFinderParams->_buffer = DDS_StringSeq_allocbuf (1);
    checkHandle(nameFinderParams->_buffer, "DDS_StringSeq_allocbuf");
    nameFinderParams->_buffer[0] = DDS_string_alloc ( MAX_INT_LENGTH  );
    checkHandle(nameFinderParams->_buffer[0], "DDS_string_alloc");
    strcpy(nameFinderParams->_buffer[0], "0");
    DDS_sequence_set_release(nameFinderParams, TRUE);

    /* Create a QueryCondition to only read corresponding nameService information by key-value. */
    nameFinder = DDS_DataReader_create_querycondition( 
        nameServiceDR, 
        DDS_ANY_SAMPLE_STATE, 
        DDS_ANY_VIEW_STATE, 
        DDS_ANY_INSTANCE_STATE,
        nameFinderExpr, 
        nameFinderParams);
    checkHandle(nameFinder, "DDS_DataReader_create_querycondition (nameFinder)");
    
    /* Create the Topic that simulates the multi-topic (use Qos from chatMessage).*/
    namedMessageQos = DDS_TopicQos__alloc();
    checkHandle(namedMessageQos, "DDS_TopicQos__alloc");
    status = DDS_Topic_get_qos(chatMessageTopic, namedMessageQos);
    checkStatus(status, "DDS_Topic_get_qos");
    
    /* Create the NamedMessage Topic whose samples simulate the MultiTopic */
    namedMessageTopic = DDS_DomainParticipant_create_topic( 
        participant, 
        "Chat_NamedMessage", 
        type_name, 
        namedMessageQos, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(namedMessageTopic, "DDS_DomainParticipant_create_topic (NamedMessage)");
    
    /* Adapt the default PublisherQos to write into the "ChatRoom" Partition. */
    pub_qos = DDS_PublisherQos__alloc();
    checkHandle(pub_qos, "DDS_PublisherQos__alloc");
    status = DDS_DomainParticipant_get_default_publisher_qos (participant, pub_qos);
    checkStatus(status, "DDS_DomainParticipant_get_default_publisher_qos");
    pub_qos->partition.name._length = 1;
    pub_qos->partition.name._maximum = 1;
    pub_qos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    checkHandle(pub_qos->partition.name._buffer, "DDS_StringSeq_allocbuf");
    pub_qos->partition.name._buffer[0] = DDS_string_alloc ( strlen(partitionName) );
    checkHandle(pub_qos->partition.name._buffer[0], "DDS_string_alloc");
    strcpy (pub_qos->partition.name._buffer[0], partitionName);

    /* Create a private Publisher for the multitopic simulator. */
    multiPub = DDS_DomainParticipant_create_publisher(participant, pub_qos, NULL, DDS_STATUS_MASK_NONE);
    checkHandle(multiPub, "DDS_DomainParticipant_create_publisher (for multitopic)");
    
    /* Create a DataWriter for the multitopic. */
    namedMessageDW = DDS_Publisher_create_datawriter( 
        multiPub, 
        namedMessageTopic, 
        DDS_DATAWRITER_QOS_USE_TOPIC_QOS, 
        NULL,
        DDS_STATUS_MASK_NONE);
    checkHandle(namedMessageDW, "DDS_Publisher_create_datawriter (NamedMessage)");

    /* Allocate the DataReaderListener interface. */
    msgListener = DDS_DataReaderListener__alloc();
    checkHandle(msgListener, "DDS_DataReaderListener__alloc");

    /* Fill the listener_data with pointers to all entities needed by the Listener implementation. */
    listener_state = malloc(sizeof(struct MsgListenerState));
    checkHandle(listener_state, "malloc");
    listener_state->chatMessageDR = chatMessageDR;
    listener_state->nameServiceDR = nameServiceDR;
    listener_state->namedMessageDW = namedMessageDW;
    listener_state->nameFinder = nameFinder;
    listener_state->nameFinderParams = nameFinderParams;
    msgListener->listener_data = listener_state;

    /* Assign the function pointer attributes to their implementation functions. */
    msgListener->on_data_available = (void (*)(void *, DDS_DataReader)) on_message_available;
    msgListener->on_requested_deadline_missed = NULL;
    msgListener->on_requested_incompatible_qos = NULL;
    msgListener->on_sample_rejected = NULL;
    msgListener->on_liveliness_changed = NULL;
    msgListener->on_subscription_matched = NULL;
    msgListener->on_sample_lost = NULL;
    
    /* Attach the DataReaderListener to the DataReader, only enabling the data_available event. */
    status = DDS_DataReader_set_listener(chatMessageDR, msgListener, DDS_DATA_AVAILABLE_STATUS);
    checkStatus(status, "DDS_DataReader_set_listener");
    
    /* Free up all resources that are no longer needed. */
    DDS_free(namedMessageQos);
    DDS_free(sub_qos);
    DDS_free(pub_qos);
    
    /* Return the simulated Multitopic. */
    return namedMessageTopic;
}