static int subscriber_main(int domainId, int sample_count)
{
    DDS_DomainParticipant *participant = NULL;
    DDS_Subscriber *subscriber = NULL;
    DDS_Topic *topic = NULL;
    DDS_DataReader *reader = NULL;
    DDS_ReturnCode_t retcode;
    const char *type_name = NULL;
    int count = 0;
    struct DDS_Duration_t wait_timeout = {1,0};
    /* Additional variables for this example */
    int i;
    DDS_WaitSet *waitset = NULL;
    DDS_QueryCondition* query_condition = NULL;
    waitset_query_condDataReader *waitset_query_cond_reader = NULL;
    const char* query_expression = DDS_String_dup("name MATCH %0");
    struct DDS_StringSeq query_parameters;
    struct DDS_ConditionSeq active_conditions_seq =
                DDS_SEQUENCE_INITIALIZER;
    struct waitset_query_condSeq data_seq = DDS_SEQUENCE_INITIALIZER;
    struct DDS_SampleInfoSeq info_seq = DDS_SEQUENCE_INITIALIZER;
    /* Auxiliary variables */
    char * odd_string = DDS_String_dup("'ODD'");
    char * even_string = DDS_String_dup("'EVEN'");
    /* The initial value of the param_list is EVEN string */
    const char* param_list[] = {even_string};

    /* To customize participant QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    participant = DDS_DomainParticipantFactory_create_participant(
        DDS_TheParticipantFactory, domainId, &DDS_PARTICIPANT_QOS_DEFAULT,
        NULL /* listener */, DDS_STATUS_MASK_NONE);
    if (participant == NULL) {
        printf("create_participant error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* To customize subscriber QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    subscriber = DDS_DomainParticipant_create_subscriber(
        participant, &DDS_SUBSCRIBER_QOS_DEFAULT, NULL /* listener */,
        DDS_STATUS_MASK_NONE);
    if (subscriber == NULL) {
        printf("create_subscriber error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* Register the type before creating the topic */
    type_name = waitset_query_condTypeSupport_get_type_name();
    retcode = waitset_query_condTypeSupport_register_type(participant,
            type_name);
    if (retcode != DDS_RETCODE_OK) {
        printf("register_type error %d\n", retcode);
        subscriber_shutdown(participant);
        return -1;
    }

    /* To customize topic QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    topic = DDS_DomainParticipant_create_topic(
        participant, "Example waitset_query_cond",
        type_name, &DDS_TOPIC_QOS_DEFAULT, NULL /* listener */,
        DDS_STATUS_MASK_NONE);
    if (topic == NULL) {
        printf("create_topic error\n");
        subscriber_shutdown(participant);
        return -1;
    }
    
    /* To customize data reader QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    reader = DDS_Subscriber_create_datareader(
        subscriber, DDS_Topic_as_topicdescription(topic),
        &DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    if (reader == NULL) {
        printf("create_datareader error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* Narrow the reader into your specific data type */
    waitset_query_cond_reader = waitset_query_condDataReader_narrow(reader);
    if (waitset_query_cond_reader == NULL) {
        printf("DataReader narrow error\n");
        return -1;
    }

    /* Create query condition */

    DDS_StringSeq_initialize(&query_parameters);
    DDS_StringSeq_set_maximum(&query_parameters, 1);
    
    /*Here we set the default filter using the param_list */
    DDS_StringSeq_from_array(&query_parameters, param_list, 1);

    query_condition = DDS_DataReader_create_querycondition(
        reader,
        DDS_NOT_READ_SAMPLE_STATE,
        DDS_ANY_VIEW_STATE,
        DDS_ANY_INSTANCE_STATE,
        query_expression,
        &query_parameters);
    if (query_condition == NULL) {
        printf("create_query_condition error\n");
        subscriber_shutdown(participant);
        return -1;
    }
    
    waitset = DDS_WaitSet_new();
    if (waitset == NULL) {
        printf("create waitset error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* Attach Query Conditions */
    retcode = DDS_WaitSet_attach_condition(waitset,
            (DDS_Condition*)query_condition);
    if (retcode != DDS_RETCODE_OK) {
        printf("attach_condition error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    printf ("\n>>>Timeout: %.0d sec & %d nanosec\n",wait_timeout.sec,
            wait_timeout.nanosec);
    printf (">>> Query conditions: name MATCH %%0\n");
    printf ("\t%%0 = %s\n", param_list[0]);
    printf ("---------------------------------\n\n");

    /* Main loop */
    for (count=0; (sample_count == 0) || (count < sample_count); ++count) {
        
        /* We set a new parameter in the Query Condition after 7 secs */
        if (count == 7) {
            param_list[0] = odd_string;
            printf ("CHANGING THE QUERY CONDITION\n");
            printf ("\n>>> Query conditions: name MATCH %%0\n");
            printf ("\t%%0 = %s\n", param_list[0]);
            printf (">>> We keep one sample in the history\n");
            printf ("-------------------------------------\n\n");
            DDS_StringSeq_from_array(&query_parameters, param_list, 1);
            DDS_QueryCondition_set_query_parameters(query_condition,
                    &query_parameters);
            
        }
        /* wait() blocks execution of the thread until one or more attached
         * Conditions become true, or until a user-specified timeout expires.
         */
        retcode = DDS_WaitSet_wait(
                waitset,                       /* waitset */
                &active_conditions_seq,        /* active conditions sequence */
                &wait_timeout);                /* timeout */
        
        /* We get to timeout if no conditions were triggered */
        if (retcode == DDS_RETCODE_TIMEOUT) {
            printf("Wait timed out!! No conditions were triggered.\n");
            continue;
        } else if (retcode != DDS_RETCODE_OK) {
            printf("wait returned error: %d", retcode);
            break;
        }

        retcode = DDS_RETCODE_OK;
            while (retcode != DDS_RETCODE_NO_DATA) {
                retcode = 
                    waitset_query_condDataReader_take_w_condition(
                        waitset_query_cond_reader, &data_seq, &info_seq,
                        DDS_LENGTH_UNLIMITED, 
                        DDS_QueryCondition_as_readcondition(query_condition));
                    
                for (i = 0; i < waitset_query_condSeq_get_length(&data_seq);
                        ++i) {
                    if (!DDS_SampleInfoSeq_get_reference(
                            &info_seq, i)->valid_data) {
                        printf("Got metadata\n");
                        continue;
                    }
                    waitset_query_condTypeSupport_print_data(
                        waitset_query_condSeq_get_reference(&data_seq, i));
                }
                waitset_query_condDataReader_return_loan(
                    waitset_query_cond_reader, &data_seq, &info_seq);
            }
        }

    /* Cleanup and delete all entities */ 
    return subscriber_shutdown(participant);
}
static int subscriber_main(int domainId, int sample_count)
{
    DDS_DomainParticipant *participant = NULL;
    DDS_Subscriber *subscriber = NULL;
    DDS_Topic *topic = NULL;
    struct DDS_DataReaderListener reader_listener =
        DDS_DataReaderListener_INITIALIZER;
    DDS_DataReader *reader = NULL;
    DDS_ReturnCode_t retcode;
    const char *type_name = NULL;
    int count = 0;
    DDS_StatusCondition *status_condition;
    DDS_WaitSet *waitset = NULL;
    waitset_statuscondDataReader *waitsets_reader = NULL;
    struct DDS_Duration_t timeout = {4,0};

    /* To customize participant QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    participant = DDS_DomainParticipantFactory_create_participant(
        DDS_TheParticipantFactory, domainId, &DDS_PARTICIPANT_QOS_DEFAULT,
        NULL /* listener */, DDS_STATUS_MASK_NONE);
    if (participant == NULL) {
        printf("create_participant error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* To customize subscriber QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    subscriber = DDS_DomainParticipant_create_subscriber(
        participant, &DDS_SUBSCRIBER_QOS_DEFAULT, NULL /* listener */,
        DDS_STATUS_MASK_NONE);
    if (subscriber == NULL) {
        printf("create_subscriber error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    /* Register the type before creating the topic */
    type_name = waitset_statuscondTypeSupport_get_type_name();
    retcode = waitset_statuscondTypeSupport_register_type(participant, type_name);
    if (retcode != DDS_RETCODE_OK) {
        printf("register_type error %d\n", retcode);
        subscriber_shutdown(participant);
        return -1;
    }

    /* To customize topic QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    topic = DDS_DomainParticipant_create_topic(
        participant, "Example waitset_statuscond",
        type_name, &DDS_TOPIC_QOS_DEFAULT, NULL /* listener */,
        DDS_STATUS_MASK_NONE);
    if (topic == NULL) {
        printf("create_topic error\n");
        subscriber_shutdown(participant);
        return -1;
    }


    /* To customize data reader QoS, use 
       the configuration file USER_QOS_PROFILES.xml */
    reader = DDS_Subscriber_create_datareader(
        subscriber, DDS_Topic_as_topicdescription(topic),
        &DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    if (reader == NULL) {
        printf("create_datareader error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    status_condition = DDS_Entity_get_statuscondition((DDS_Entity*)reader);
    if (status_condition == NULL) {
        printf("get_statuscondition error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    // Since a single status condition can match many statuses, 
    // enable only those we're interested in.
    retcode = DDS_StatusCondition_set_enabled_statuses(
        status_condition,
        DDS_DATA_AVAILABLE_STATUS);
    if (retcode != DDS_RETCODE_OK) {
        printf("set_enabled_statuses error\n");
        subscriber_shutdown(participant);
        return -1;
    }

    // Create WaitSet, and attach conditions
    waitset = DDS_WaitSet_new();
    if (waitset == NULL) {
        printf("create waitset error\n");
        subscriber_shutdown(participant);
        return -1;        
    }


    retcode = DDS_WaitSet_attach_condition(waitset, (DDS_Condition*)status_condition);
    if (retcode != DDS_RETCODE_OK) {
        printf("attach_condition error\n");
        subscriber_shutdown(participant);
        return -1;
    }    

    // Get narrowed datareader
    waitsets_reader = waitset_statuscondDataReader_narrow(reader);
    if (waitsets_reader == NULL) {
        printf("DataReader narrow error\n");
        return -1;
    }

    /* Main loop */
    for (count=0; (sample_count == 0) || (count < sample_count); ++count) {
        struct DDS_ConditionSeq active_conditions = DDS_SEQUENCE_INITIALIZER;
        int i, j;

        retcode = DDS_WaitSet_wait(waitset, &active_conditions, &timeout);
        if (retcode == DDS_RETCODE_TIMEOUT) {
            printf("wait timed out\n");
            count+=2;
            continue;
        } else if (retcode != DDS_RETCODE_OK) {
            printf("wait returned error: %d\n", retcode);
            break;
        }

        printf("got %d active conditions\n",
               DDS_ConditionSeq_get_length(&active_conditions));
        
        for (i = 0; i < DDS_ConditionSeq_get_length(&active_conditions); ++i) {
            if (DDS_ConditionSeq_get(&active_conditions, i) == (DDS_Condition*)status_condition) {
                // A status condition triggered--see which ones
                DDS_StatusMask triggeredmask;
                triggeredmask = DDS_Entity_get_status_changes((DDS_Entity*)waitsets_reader);

                if (triggeredmask & DDS_DATA_AVAILABLE_STATUS) {
                    struct waitset_statuscondSeq data_seq = 
                        DDS_SEQUENCE_INITIALIZER;
                    struct DDS_SampleInfoSeq info_seq = 
                        DDS_SEQUENCE_INITIALIZER;
                
                    retcode = waitset_statuscondDataReader_take(
                        waitsets_reader, &data_seq, &info_seq,
                        DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
                        DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
                    if (retcode != DDS_RETCODE_OK) {
                        printf("take error %d\n", retcode);
                        break;
                    }
                
                    for (j = 0; j < waitset_statuscondSeq_get_length(&data_seq); ++j) {
                        if (!DDS_SampleInfoSeq_get_reference(&info_seq, j)->valid_data) {
                            printf("   Got metadata\n");                     
                            continue;
                        }
                        waitset_statuscondTypeSupport_print_data(
                            waitset_statuscondSeq_get_reference(&data_seq, j));
                    }

                    retcode = waitset_statuscondDataReader_return_loan(
                        waitsets_reader, &data_seq, &info_seq);
                    if (retcode != DDS_RETCODE_OK) {
                        printf("return loan error %d\n", retcode);
                    }

                }

            }
        }
    }    

    /* Delete all entities */
    retcode = DDS_WaitSet_delete(waitset);
    if (retcode != DDS_RETCODE_OK) {
        printf("delete waitset error %d\n", retcode);
    }

    /* Cleanup and delete all entities */ 
    return subscriber_shutdown(participant);
}