static void *imu_reader (void *args) { DDS_DynamicDataReader dr; DDS_WaitSet ws; DDS_SampleStateMask ss = DDS_NOT_READ_SAMPLE_STATE; DDS_ViewStateMask vs = DDS_ANY_VIEW_STATE; DDS_InstanceStateMask is = DDS_ANY_INSTANCE_STATE; DDS_ReadCondition rc; DDS_ConditionSeq conds = DDS_SEQ_INITIALIZER (DDS_Condition); DDS_Duration_t to; DDS_ReturnCode_t ret; dr = args; ws = DDS_WaitSet__alloc (); if (!ws) fatal ("Unable to allocate a WaitSet!"); if (verbose) printf ("DDS Waitset allocated.\r\n"); rc = DDS_DataReader_create_readcondition (dr, ss, vs, is); if (!rc) fatal ("DDS_DataReader_create_readcondition () returned an error!"); if (verbose) printf ("DDS Readcondition created.\r\n"); ret = DDS_WaitSet_attach_condition (ws, rc); if (ret) fatal ("Unable to attach condition to a WaitSet!"); while (!aborting) { to.sec = 0; to.nanosec = 200000000; /* Timeout after 200ms. */ ret = DDS_WaitSet_wait (ws, &conds, &to); if (ret == DDS_RETCODE_TIMEOUT) continue; read_msg (NULL, dr); } ret = DDS_WaitSet_detach_condition (ws, rc); if (ret) fatal ("Unable to detach condition from WaitSet (%s)!", DDS_error (ret)); DDS_WaitSet__free (ws); return (NULL); }
int main ( int argc, char *argv[]) { DDS_DomainId_t myDomain = DDS_OBJECT_NIL; DDS_DomainParticipantFactory dpf = DDS_OBJECT_NIL; DDS_DomainParticipant dp = DDS_OBJECT_NIL; DDS_Publisher p = DDS_OBJECT_NIL; DDS_Subscriber s = DDS_OBJECT_NIL; pingpong_PP_min_msgDataWriter PP_min_writer = DDS_OBJECT_NIL; pingpong_PP_seq_msgDataWriter PP_seq_writer = DDS_OBJECT_NIL; pingpong_PP_string_msgDataWriter PP_string_writer = DDS_OBJECT_NIL; pingpong_PP_fixed_msgDataWriter PP_fixed_writer = DDS_OBJECT_NIL; pingpong_PP_array_msgDataWriter PP_array_writer = DDS_OBJECT_NIL; pingpong_PP_bseq_msgDataWriter PP_bseq_writer = DDS_OBJECT_NIL; pingpong_PP_min_msgDataReader PP_min_reader = DDS_OBJECT_NIL; pingpong_PP_seq_msgDataReader PP_seq_reader = DDS_OBJECT_NIL; pingpong_PP_string_msgDataReader PP_string_reader = DDS_OBJECT_NIL; pingpong_PP_fixed_msgDataReader PP_fixed_reader = DDS_OBJECT_NIL; pingpong_PP_array_msgDataReader PP_array_reader = DDS_OBJECT_NIL; pingpong_PP_bseq_msgDataReader PP_bseq_reader = DDS_OBJECT_NIL; pingpong_PP_quit_msgDataReader PP_quit_reader = DDS_OBJECT_NIL; pingpong_PP_min_msgTypeSupport PP_min_dt; pingpong_PP_seq_msgTypeSupport PP_seq_dt; pingpong_PP_string_msgTypeSupport PP_string_dt; pingpong_PP_fixed_msgTypeSupport PP_fixed_dt; pingpong_PP_array_msgTypeSupport PP_array_dt; pingpong_PP_bseq_msgTypeSupport PP_bseq_dt; pingpong_PP_quit_msgTypeSupport PP_quit_dt; DDS_sequence_pingpong_PP_min_msg PP_min_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_seq_msg PP_seq_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_string_msg PP_string_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_fixed_msg PP_fixed_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_array_msg PP_array_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_bseq_msg PP_bseq_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_pingpong_PP_quit_msg PP_quit_dataList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_StatusCondition PP_min_sc; DDS_StatusCondition PP_seq_sc; DDS_StatusCondition PP_string_sc; DDS_StatusCondition PP_fixed_sc; DDS_StatusCondition PP_array_sc; DDS_StatusCondition PP_bseq_sc; DDS_StatusCondition PP_quit_sc; DDS_Topic PP_min_topic = DDS_OBJECT_NIL; DDS_Topic PP_seq_topic = DDS_OBJECT_NIL; DDS_Topic PP_string_topic = DDS_OBJECT_NIL; DDS_Topic PP_fixed_topic = DDS_OBJECT_NIL; DDS_Topic PP_array_topic = DDS_OBJECT_NIL; DDS_Topic PP_bseq_topic = DDS_OBJECT_NIL; DDS_Topic PP_quit_topic = DDS_OBJECT_NIL; DDS_ConditionSeq *conditionList; DDS_SampleInfoSeq infoList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_WaitSet w; DDS_DomainParticipantQos *dpQos; DDS_TopicQos *tQos; DDS_PublisherQos *pQos; DDS_DataWriterQos *dwQos; DDS_SubscriberQos *sQos; DDS_DataReaderQos *drQos; DDS_boolean terminate = FALSE; DDS_ReturnCode_t result; int i; int imax; int j; int jmax; printf ("Starting pong example\n"); fflush(stdout); /* * Evaluate cmdline arguments */ #ifdef INTEGRITY read_partition = "PongRead"; write_partition = "PongWrite"; #else if (argc != 1) { if (argc != 3) { printf ("Invalid.....\n Usage: %s [READ_PARTITION WRITE_PARTITION]\n", argv[0]); exit (1); } read_partition = argv[1]; write_partition = argv[2]; } #endif /* * Create WaitSet */ w = DDS_WaitSet__alloc (); /* * Initialize Qos variables */ dpQos = DDS_DomainParticipantQos__alloc(); tQos = DDS_TopicQos__alloc(); pQos = DDS_PublisherQos__alloc(); dwQos = DDS_DataWriterQos__alloc(); sQos = DDS_SubscriberQos__alloc(); drQos = DDS_DataReaderQos__alloc(); /* * Initialize condition list */ conditionList = NULL; /* * Create participant */ dpf = DDS_DomainParticipantFactory_get_instance (); dp = DDS_DomainParticipantFactory_create_participant (dpf, myDomain, DDS_PARTICIPANT_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); if (dp == DDS_OBJECT_NIL) { printf ("%s PONG: ERROR - Splice Daemon not running\n", argv[0]); exit(1); } /* * Create PONG publisher */ DDS_DomainParticipant_get_default_publisher_qos (dp, pQos); pQos->partition.name._length = 1; pQos->partition.name._maximum = 1; pQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); pQos->partition.name._buffer[0] = DDS_string_alloc (strlen (write_partition) + 1); strcpy (pQos->partition.name._buffer[0], write_partition); p = DDS_DomainParticipant_create_publisher (dp, pQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (pQos); /* * Create PING subscriber */ DDS_DomainParticipant_get_default_subscriber_qos (dp, sQos); sQos->partition.name._length = 1; sQos->partition.name._maximum = 1; sQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); sQos->partition.name._buffer[0] = DDS_string_alloc (strlen (read_partition) + 1); strcpy (sQos->partition.name._buffer[0], read_partition); s = DDS_DomainParticipant_create_subscriber (dp, sQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (sQos); /* * PP_min_msg */ /* Create Topic */ PP_min_dt = pingpong_PP_min_msgTypeSupport__alloc (); pingpong_PP_min_msgTypeSupport_register_type (PP_min_dt, dp, "pingpong::PP_min_msg"); PP_min_topic = DDS_DomainParticipant_create_topic (dp, "PP_min_topic", "pingpong::PP_min_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_min_writer = DDS_Publisher_create_datawriter (p, PP_min_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_min_reader = DDS_Subscriber_create_datareader (s, PP_min_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_min_sc = DDS_DataReader_get_statuscondition (PP_min_reader); DDS_StatusCondition_set_enabled_statuses (PP_min_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_min_sc); /* * PP_seq_msg */ /* Create Topic */ PP_seq_dt = pingpong_PP_seq_msgTypeSupport__alloc (); pingpong_PP_seq_msgTypeSupport_register_type (PP_seq_dt, dp, "pingpong::PP_seq_msg"); PP_seq_topic = DDS_DomainParticipant_create_topic (dp, "PP_seq_topic", "pingpong::PP_seq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_seq_writer = DDS_Publisher_create_datawriter (p, PP_seq_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_seq_reader = DDS_Subscriber_create_datareader (s, PP_seq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_seq_sc = DDS_DataReader_get_statuscondition (PP_seq_reader); DDS_StatusCondition_set_enabled_statuses (PP_seq_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_seq_sc); /* * PP_string_msg */ /* Create Topic */ PP_string_dt = pingpong_PP_string_msgTypeSupport__alloc (); pingpong_PP_string_msgTypeSupport_register_type (PP_string_dt, dp, "pingpong::PP_string_msg"); PP_string_topic = DDS_DomainParticipant_create_topic (dp, "PP_string_topic", "pingpong::PP_string_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_string_writer = DDS_Publisher_create_datawriter (p, PP_string_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_string_reader = DDS_Subscriber_create_datareader (s, PP_string_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_string_sc = DDS_DataReader_get_statuscondition (PP_string_reader); DDS_StatusCondition_set_enabled_statuses (PP_string_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_string_sc); /* * PP_fixed_msg */ /* Create Topic */ PP_fixed_dt = pingpong_PP_fixed_msgTypeSupport__alloc (); pingpong_PP_fixed_msgTypeSupport_register_type (PP_fixed_dt, dp, "pingpong::PP_fixed_msg"); PP_fixed_topic = DDS_DomainParticipant_create_topic (dp, "PP_fixed_topic", "pingpong::PP_fixed_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_fixed_writer = DDS_Publisher_create_datawriter (p, PP_fixed_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_fixed_reader = DDS_Subscriber_create_datareader (s, PP_fixed_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_fixed_sc = DDS_DataReader_get_statuscondition (PP_fixed_reader); DDS_StatusCondition_set_enabled_statuses (PP_fixed_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_fixed_sc); /* * PP_array_msg */ /* Create Topic */ PP_array_dt = pingpong_PP_array_msgTypeSupport__alloc (); pingpong_PP_array_msgTypeSupport_register_type (PP_array_dt, dp, "pingpong::PP_array_msg"); PP_array_topic = DDS_DomainParticipant_create_topic (dp, "PP_array_topic", "pingpong::PP_array_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_array_writer = DDS_Publisher_create_datawriter (p, PP_array_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_array_reader = DDS_Subscriber_create_datareader (s, PP_array_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_array_sc = DDS_DataReader_get_statuscondition (PP_array_reader); DDS_StatusCondition_set_enabled_statuses (PP_array_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_array_sc); /* * PP_bseq_msg */ /* Create Topic */ PP_bseq_dt = pingpong_PP_bseq_msgTypeSupport__alloc (); pingpong_PP_bseq_msgTypeSupport_register_type (PP_bseq_dt, dp, "pingpong::PP_bseq_msg"); PP_bseq_topic = DDS_DomainParticipant_create_topic (dp, "PP_bseq_topic", "pingpong::PP_bseq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_bseq_writer = DDS_Publisher_create_datawriter (p, PP_bseq_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_bseq_reader = DDS_Subscriber_create_datareader (s, PP_bseq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_bseq_sc = DDS_DataReader_get_statuscondition (PP_bseq_reader); DDS_StatusCondition_set_enabled_statuses (PP_bseq_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_bseq_sc); /* * PP_quit_msg */ /* Create Topic */ PP_quit_dt = pingpong_PP_quit_msgTypeSupport__alloc (); pingpong_PP_quit_msgTypeSupport_register_type (PP_quit_dt, dp, "pingpong::PP_quit_msg"); PP_quit_topic = DDS_DomainParticipant_create_topic (dp, "PP_quit_topic", "pingpong::PP_quit_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_quit_reader = DDS_Subscriber_create_datareader (s, PP_quit_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_quit_sc = DDS_DataReader_get_statuscondition (PP_quit_reader); DDS_StatusCondition_set_enabled_statuses (PP_quit_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_quit_sc); while (!terminate) { DDS_Duration_t wait_timeout = DDS_DURATION_INFINITE; /* printf ("PONG: waiting for PING\n"); */ conditionList = DDS_ConditionSeq__alloc(); result = DDS_WaitSet_wait (w, conditionList, &wait_timeout); if (result == DDS_RETCODE_OK) { imax = conditionList->_length; for (i = 0; i < imax; i++) { if (conditionList->_buffer[i] == PP_min_sc) { /* printf ("PONG: PING_min arrived\n"); */ result = pingpong_PP_min_msgDataReader_take (PP_min_reader, &PP_min_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_min_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_min_msgDataWriter_write (PP_min_writer, &PP_min_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_min_msgDataReader_return_loan (PP_min_reader, &PP_min_dataList, &infoList); } else { printf ("PONG: PING_min triggered, but no data available\n"); } } else if (conditionList->_buffer[i] == PP_seq_sc) { /* printf ("PONG: PING_seq arrived\n"); */ result = pingpong_PP_seq_msgDataReader_take (PP_seq_reader, &PP_seq_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_seq_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_seq_msgDataWriter_write (PP_seq_writer, &PP_seq_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_seq_msgDataReader_return_loan (PP_seq_reader, &PP_seq_dataList, &infoList); } else { printf ("PONG: PING_seq triggered, but no data available\n"); } } else if (conditionList->_buffer[i] == PP_string_sc) { /* printf ("PONG: PING_string arrived\n"); */ result = pingpong_PP_string_msgDataReader_take (PP_string_reader, &PP_string_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_string_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_string_msgDataWriter_write (PP_string_writer, &PP_string_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_string_msgDataReader_return_loan (PP_string_reader, &PP_string_dataList, &infoList); } else { printf ("PONG: PING_string triggered, but no data available\n"); exit(1); } } else if (conditionList->_buffer[i] == PP_fixed_sc) { /* printf ("PONG: PING_fixed arrived\n"); */ result = pingpong_PP_fixed_msgDataReader_take (PP_fixed_reader, &PP_fixed_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_fixed_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_fixed_msgDataWriter_write (PP_fixed_writer, &PP_fixed_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_fixed_msgDataReader_return_loan (PP_fixed_reader, &PP_fixed_dataList, &infoList); } else { printf ("PONG: PING_fixed triggered, but no data available\n"); } } else if (conditionList->_buffer[i] == PP_array_sc) { /* printf ("PONG: PING_array arrived\n"); */ result = pingpong_PP_array_msgDataReader_take (PP_array_reader, &PP_array_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_array_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_array_msgDataWriter_write (PP_array_writer, &PP_array_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_array_msgDataReader_return_loan (PP_array_reader, &PP_array_dataList, &infoList); } else { printf ("PONG: PING_array triggered, but no data available\n"); } } else if (conditionList->_buffer[i] == PP_bseq_sc) { /* printf ("PONG: PING_bseq arrived\n"); */ result = pingpong_PP_bseq_msgDataReader_take (PP_bseq_reader, &PP_bseq_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_bseq_dataList._length; if (jmax != 0) { for (j = 0; j < jmax; j++) { if (infoList._buffer[j].valid_data) { result = pingpong_PP_bseq_msgDataWriter_write (PP_bseq_writer, &PP_bseq_dataList._buffer[j], DDS_HANDLE_NIL); } } result = pingpong_PP_bseq_msgDataReader_return_loan (PP_bseq_reader, &PP_bseq_dataList, &infoList); } else { printf ("PONG: PING_bseq triggered, but no data available\n"); } } else if (conditionList->_buffer[i] == PP_quit_sc) { /* printf ("PONG: PING_quit arrived\n"); */ result = pingpong_PP_quit_msgDataReader_take (PP_quit_reader, &PP_quit_dataList, &infoList, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE); jmax = PP_quit_dataList._length; if (jmax != 0) { if (PP_quit_dataList._buffer[0].quit) { terminate = TRUE; } result = pingpong_PP_quit_msgDataReader_return_loan (PP_quit_reader, &PP_quit_dataList, &infoList); } else { printf ("PONG: PING_quit triggered, but no data available\n"); } } else { printf ("PONG: unknown condition triggered: %lx\n", (unsigned long)conditionList->_buffer[i]); } } } else { if (result == DDS_RETCODE_ALREADY_DELETED) { terminate = TRUE; } printf ("PONG: wait returned not ok: %d\n", result); } DDS_free(conditionList); } result = DDS_Subscriber_delete_datareader (s, PP_min_reader); result = DDS_Publisher_delete_datawriter (p, PP_min_writer); result = DDS_Subscriber_delete_datareader (s, PP_seq_reader); result = DDS_Publisher_delete_datawriter (p, PP_seq_writer); result = DDS_Subscriber_delete_datareader (s, PP_string_reader); result = DDS_Publisher_delete_datawriter (p, PP_string_writer); result = DDS_Subscriber_delete_datareader (s, PP_fixed_reader); result = DDS_Publisher_delete_datawriter (p, PP_fixed_writer); result = DDS_Subscriber_delete_datareader (s, PP_array_reader); result = DDS_Publisher_delete_datawriter (p, PP_array_writer); result = DDS_Subscriber_delete_datareader (s, PP_bseq_reader); result = DDS_Publisher_delete_datawriter (p, PP_bseq_writer); result = DDS_Subscriber_delete_datareader (s, PP_quit_reader); result = DDS_DomainParticipant_delete_subscriber (dp, s); result = DDS_DomainParticipant_delete_publisher (dp, p); result = DDS_DomainParticipant_delete_topic (dp, PP_min_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_seq_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_string_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_fixed_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_array_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_bseq_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_quit_topic); result = DDS_DomainParticipantFactory_delete_participant (dpf, dp); DDS_free (w); DDS_free (PP_min_dt); DDS_free (PP_seq_dt); DDS_free (PP_string_dt); DDS_free (PP_fixed_dt); DDS_free (PP_array_dt); DDS_free (PP_bseq_dt); DDS_free (PP_quit_dt); DDS_free (dpQos); DDS_free (tQos); DDS_free (dwQos); DDS_free (drQos); printf ("Completed pong example\n"); fflush(stdout); return 0; }
void do_dds_shell (DDS_DataWriter dw) { Vector3_t m; DDS_InstanceHandle_t h; char buf [256]; #if !defined (NUTTX_RTOS) tty_init (); DDS_Handle_attach (tty_stdin, POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL, tty_input, NULL); #endif #if 0 printf ("Welcome to the Technicolor chatroom.\r\n"); printf ("Anything you type will be sent to all chatroom attendees.\r\n"); printf ("Type '!help' for chatroom options.\r\n"); m.chatroom = chatroom; m.from = user_name; #endif h = 0; while (!aborting) { #if defined (NUTTX_RTOS) /* Take into account that fgets reads the "\n" character at the end of each line. Code should consider this aspect in every case */ fgets(buf, 256, stdin); #else tty_gets (sizeof (buf), buf, 0, 1); #endif if (buf [0] == '!') { #if defined (NUTTX_RTOS) if (!strcmp (buf + 1, "quit\n") || (buf [1] == 'q' && buf [2] == '\n')) { #else if (!strcmp (buf + 1, "quit") || (buf [1] == 'q' && buf [2] == '\0')) { #endif aborting = 1; break; } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "list\n")) #else else if (!strcmp (buf + 1, "list")) #endif printf ("Attendees:\r\n\t%s\r\n", user_name); #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "user\n", 4)) { #else else if (!memcmp (buf + 1, "user", 4)) { #endif if (h) { Vector3_signal (dw, h, 1); h = 0; } strcpy (user_name, buf + 6); printf ("You are now: %s\r\n", user_name); } #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "room\n", 4)) { #else else if (!memcmp (buf + 1, "room", 4)) { #endif if (h) { Vector3_signal (dw, h, 1); h = 0; } strcpy (chatroom, buf + 6); printf ("Switched to chatroom: %s\r\n", chatroom); } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "info\n")) #else else if (!strcmp (buf + 1, "info")) #endif printf ("Chatroom: %s, Username: %s\r\n", chatroom, user_name); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "busy\n")) #else else if (!strcmp (buf + 1, "busy")) #endif Vector3_signal (dw, h, 0); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "away\n")) { #else else if (!strcmp (buf + 1, "away")) { #endif if (h) { Vector3_signal (dw, h, 1); h = 0; } } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "help\n") || (buf [1] == 'h' && buf [2] == '\n\0') || (buf [1] == '?' && buf [2] == '\n\0')) { #else else if (!strcmp (buf + 1, "help") || (buf [1] == 'h' && buf [2] == '\0') || (buf [1] == '?' && buf [2] == '\0')) { #endif printf ("Commands:\r\n"); printf (" !room <room_name> -> set the chatroom name.\r\n"); printf (" !user <user_name> -> set the user name.\r\n"); printf (" !list -> list the attendees.\r\n"); printf (" !info -> show chatroom and user.\r\n"); printf (" !busy -> momentarily not involved.\r\n"); printf (" !away -> gone away.\r\n"); printf (" !help or !h or !? -> Show this info.\r\n"); printf (" !quit or !q -> Quit the chatroom.\r\n"); printf (" !!<command> -> DDS debug command.\r\n"); /* printf (" !$<command> -> Shell command.\r\n"); */ } else if (buf [1] == '!') DDS_Debug_command (buf + 2); /* else if (buf [1] == '$') system (buf + 2); */ else printf ("?%s\r\n", buf + 1); continue; } else { printf("Writing to the other endpoints not allowed.\n"); #if 0 if (!h) h = ChatMsg_register (dw, &m); //sprintf(buf_t, "Embedded says %s\n", buf); fetch_imu(); //m.message = buf_t; m.message = buf; ChatMsg_write (dw, &m, h); #endif printf ("Commands:\r\n"); printf (" !list -> list the attendees.\r\n"); printf (" !busy -> momentarily not involved.\r\n"); printf (" !away -> gone away.\r\n"); printf (" !help or !h or !? -> Show this info.\r\n"); printf (" !quit or !q -> Quit the chatroom.\r\n"); printf (" !!<command> -> DDS debug command.\r\n"); } } } static void *dds_send_imu (void *args) { Vector3_t m; DDS_InstanceHandle_t h; h = 0; for (;;){ sleep (1); // sleep 0.5 seconds //sprintf(buf_t, "Embedded says %s\n", buf); m.x_ = 1; m.y_ = 2; m.z_ = 3; #if 0 /* According to https://github.com/brunodebus/tinq-core/issues/7#issuecomment-63740498: the Vector3 shouldn't be registered if it doesn't contain a @key attribute */ if (!h) h = Vector3_register (dw, &m); #endif Vector3_write (dw, &m, h); } } void read_msg (DDS_DataReaderListener *l, DDS_DataReader dr) { Vector3_t msg; DDS_InstanceStateKind kind; int valid; DDS_ReturnCode_t ret; ARG_NOT_USED (l) memset (&msg, 0, sizeof (msg)); ret = Vector3_read_or_take (dr, &msg, DDS_NOT_READ_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE, 1, &valid, &kind); if (ret == DDS_RETCODE_OK) do { #if 0 /* Use a from field within the message to avoid to read the messages that this node sent. */ #ifndef DISPLAY_SELF if (!strcmp (msg.from, user_name) && !strcmp (msg.chatroom, chatroom)) break; #endif #endif if (valid) printf ("IMU accel message: x=%f, y=%f and z=%f\r\n", msg.x_, msg.y_, msg.z_); else if (kind == DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE) printf ("DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE!\r\n"); else if (kind == DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE) printf ("DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE!\r\n"); } while (0); Vector3_cleanup (&msg); } #ifdef WAITSETS static void *imu_reader (void *args) { DDS_DynamicDataReader dr; DDS_WaitSet ws; DDS_SampleStateMask ss = DDS_NOT_READ_SAMPLE_STATE; DDS_ViewStateMask vs = DDS_ANY_VIEW_STATE; DDS_InstanceStateMask is = DDS_ANY_INSTANCE_STATE; DDS_ReadCondition rc; DDS_ConditionSeq conds = DDS_SEQ_INITIALIZER (DDS_Condition); DDS_Duration_t to; DDS_ReturnCode_t ret; dr = args; ws = DDS_WaitSet__alloc (); if (!ws) fatal ("Unable to allocate a WaitSet!"); if (verbose) printf ("DDS Waitset allocated.\r\n"); rc = DDS_DataReader_create_readcondition (dr, ss, vs, is); if (!rc) fatal ("DDS_DataReader_create_readcondition () returned an error!"); if (verbose) printf ("DDS Readcondition created.\r\n"); ret = DDS_WaitSet_attach_condition (ws, rc); if (ret) fatal ("Unable to attach condition to a WaitSet!"); while (!aborting) { to.sec = 0; to.nanosec = 200000000; /* Timeout after 200ms. */ ret = DDS_WaitSet_wait (ws, &conds, &to); if (ret == DDS_RETCODE_TIMEOUT) continue; read_msg (NULL, dr); } ret = DDS_WaitSet_detach_condition (ws, rc); if (ret) fatal ("Unable to detach condition from WaitSet (%s)!", DDS_error (ret)); DDS_WaitSet__free (ws); return (NULL); } static void start_imu_reader (DDS_DynamicDataReader dr) { thread_create (rt, imu_reader, dr); }
int main ( int argc, char *argv[] ) { DDS_ConditionSeq *conditionList; DDS_WaitSet w; DDS_Condition exp_condition; pong_handler *active_handler; DDS_DomainParticipantQos *dpQos; DDS_TopicQos *tQos; DDS_PublisherQos *pQos; DDS_DataWriterQos *dwQos; DDS_SubscriberQos *sQos; DDS_DataReaderQos *drQos; time_t clock = time (NULL); DDS_Duration_t wait_timeout = {3,0}; DDS_ReturnCode_t result; DDS_boolean finish_flag = FALSE; DDS_boolean timeout_flag = FALSE; DDS_boolean terminate = FALSE; int imax = 1; int i; unsigned int block; init_clock(); /* * init timing statistics */ init_stats (&roundtrip, "round_trip"); init_stats (&write_access, "write_access"); init_stats (&read_access, "read_access"); /* * Evaluate cmdline arguments */ if (argc != 1) { if (argc != 6) { printf ("Invalid.....\n Usage: %s [blocks blocksize topic_id WRITE_PARTITION READ_PARTITION]\n", argv[0]); exit (1); } nof_blocks = atoi (argv[1]); nof_cycles = atoi (argv[2]); topic_id = argv[3][0]; write_partition = argv[4]; read_partition = argv[5]; } /* * Create WaitSet */ w = DDS_WaitSet__alloc (); /* * Initialize Qos variables */ dpQos = DDS_DomainParticipantQos__alloc(); tQos = DDS_TopicQos__alloc(); pQos = DDS_PublisherQos__alloc(); dwQos = DDS_DataWriterQos__alloc(); sQos = DDS_SubscriberQos__alloc(); drQos = DDS_DataReaderQos__alloc(); /* * Initialize condition list */ conditionList = NULL; /* * Create participant */ dpf = DDS_DomainParticipantFactory_get_instance (); dp = DDS_DomainParticipantFactory_create_participant (dpf, myDomain, DDS_PARTICIPANT_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); if (dp == DDS_HANDLE_NIL) { printf ("%s PING: ERROR - Splice Daemon not running", argv[0]); exit (1); } /* * Create PING publisher */ DDS_DomainParticipant_get_default_publisher_qos (dp, pQos); pQos->partition.name._length = 1; pQos->partition.name._maximum = 1; pQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); pQos->partition.name._buffer[0] = DDS_string_alloc (strlen(write_partition) + 1); strcpy (pQos->partition.name._buffer[0], write_partition); p = DDS_DomainParticipant_create_publisher (dp, pQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (pQos); /* * Create PONG subscriber */ DDS_DomainParticipant_get_default_subscriber_qos (dp, sQos); sQos->partition.name._length = 1; sQos->partition.name._maximum = 1; sQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); sQos->partition.name._buffer[0] = DDS_string_alloc (strlen(read_partition) + 1); strcpy (sQos->partition.name._buffer[0], read_partition); s = DDS_DomainParticipant_create_subscriber (dp, sQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (sQos); /* * PP_min_msg */ /* Create Topic */ PP_min_dt = pingpong_PP_min_msgTypeSupport__alloc (); pingpong_PP_min_msgTypeSupport_register_type (PP_min_dt, dp, "pingpong::PP_min_msg"); PP_min_topic = DDS_DomainParticipant_create_topic (dp, "PP_min_topic", "pingpong::PP_min_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_min_writer = DDS_Publisher_create_datawriter (p, PP_min_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_min_reader = DDS_Subscriber_create_datareader (s, PP_min_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_min_sc = DDS_DataReader_get_statuscondition (PP_min_reader); DDS_StatusCondition_set_enabled_statuses (PP_min_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_min_sc); /* * PP_seq_msg */ /* Create Topic */ PP_seq_dt = pingpong_PP_seq_msgTypeSupport__alloc (); pingpong_PP_seq_msgTypeSupport_register_type (PP_seq_dt, dp, "pingpong::PP_seq_msg"); PP_seq_topic = DDS_DomainParticipant_create_topic (dp, "PP_seq_topic", "pingpong::PP_seq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_seq_writer = DDS_Publisher_create_datawriter (p, PP_seq_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_seq_reader = DDS_Subscriber_create_datareader (s, PP_seq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_seq_sc = DDS_DataReader_get_statuscondition (PP_seq_reader); DDS_StatusCondition_set_enabled_statuses (PP_seq_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_seq_sc); /* * PP_string_msg */ /* Create Topic */ PP_string_dt = pingpong_PP_string_msgTypeSupport__alloc (); pingpong_PP_string_msgTypeSupport_register_type (PP_string_dt, dp, "pingpong::PP_string_msg"); PP_string_topic = DDS_DomainParticipant_create_topic (dp, "PP_string_topic", "pingpong::PP_string_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_string_writer = DDS_Publisher_create_datawriter (p, PP_string_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_string_reader = DDS_Subscriber_create_datareader (s, PP_string_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_string_sc = DDS_DataReader_get_statuscondition (PP_string_reader); DDS_StatusCondition_set_enabled_statuses (PP_string_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_string_sc); /* * PP_fixed_msg */ /* Create Topic */ PP_fixed_dt = pingpong_PP_fixed_msgTypeSupport__alloc (); pingpong_PP_fixed_msgTypeSupport_register_type (PP_fixed_dt, dp, "pingpong::PP_fixed_msg"); PP_fixed_topic = DDS_DomainParticipant_create_topic (dp, "PP_fixed_topic", "pingpong::PP_fixed_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_fixed_writer = DDS_Publisher_create_datawriter (p, PP_fixed_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_fixed_reader = DDS_Subscriber_create_datareader (s, PP_fixed_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_fixed_sc = DDS_DataReader_get_statuscondition (PP_fixed_reader); DDS_StatusCondition_set_enabled_statuses (PP_fixed_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_fixed_sc); /* * PP_array_msg */ /* Create Topic */ PP_array_dt = pingpong_PP_array_msgTypeSupport__alloc (); pingpong_PP_array_msgTypeSupport_register_type (PP_array_dt, dp, "pingpong::PP_array_msg"); PP_array_topic = DDS_DomainParticipant_create_topic (dp, "PP_array_topic", "pingpong::PP_array_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_array_writer = DDS_Publisher_create_datawriter (p, PP_array_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_array_reader = DDS_Subscriber_create_datareader (s, PP_array_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_array_sc = DDS_DataReader_get_statuscondition (PP_array_reader); DDS_StatusCondition_set_enabled_statuses (PP_array_sc, DDS_DATA_AVAILABLE_STATUS); result = DDS_WaitSet_attach_condition (w, PP_array_sc); /* * PP_quit_msg */ /* Create Topic */ PP_quit_dt = pingpong_PP_quit_msgTypeSupport__alloc (); pingpong_PP_quit_msgTypeSupport_register_type (PP_quit_dt, dp, "pingpong::PP_quit_msg"); PP_quit_topic = DDS_DomainParticipant_create_topic (dp, "PP_quit_topic", "pingpong::PP_quit_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_quit_writer = DDS_Publisher_create_datawriter (p, PP_quit_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); for (block = 0; block < nof_blocks ; block++) { while (!finish_flag) { /* * Send Initial message */ timeout_flag = FALSE; switch(topic_id) { case 'm': { /* printf ("PING: sending initial ping_min\n"); */ pingpong_PP_min_msg *PPdata = pingpong_PP_min_msg__alloc (); exp_condition = PP_min_sc; active_handler = &PP_min_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); result = pingpong_PP_min_msgDataWriter_write (PP_min_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'q': { /* printf ("PING: sending initial ping_seq\n"); */ pingpong_PP_seq_msg *PPdata = pingpong_PP_seq_msg__alloc (); exp_condition = PP_seq_sc; active_handler = &PP_seq_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); result = pingpong_PP_seq_msgDataWriter_write (PP_seq_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 's': { /* printf ("PING: sending initial ping_string\n"); */ pingpong_PP_string_msg *PPdata = pingpong_PP_string_msg__alloc (); exp_condition = PP_string_sc; active_handler = &PP_string_handler; PPdata->count = 0; PPdata->block = block; PPdata->a_string = DDS_string_alloc (8); strcpy (PPdata->a_string, "a_string"); preWriteTime = timeGet (); result = pingpong_PP_string_msgDataWriter_write (PP_string_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'f': { /* printf ("PING: sending initial ping_fixed\n"); */ pingpong_PP_fixed_msg *PPdata = pingpong_PP_fixed_msg__alloc (); exp_condition = PP_fixed_sc; active_handler = &PP_fixed_handler; PPdata->count = 0; PPdata->block = block; PPdata->a_bstring = DDS_string_alloc (9); strcpy (PPdata->a_bstring, "a_bstring"); preWriteTime = timeGet (); result = pingpong_PP_fixed_msgDataWriter_write (PP_fixed_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'a': { /* printf ("PING: sending initial ping_array\n"); */ pingpong_PP_array_msg *PPdata = pingpong_PP_array_msg__alloc (); exp_condition = PP_array_sc; active_handler = &PP_array_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); result = pingpong_PP_array_msgDataWriter_write (PP_array_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 't': { /* printf ("PING: sending initial ping_quit\n"); */ pingpong_PP_quit_msg *PPdata = pingpong_PP_quit_msg__alloc(); PPdata->quit = TRUE; terminate = TRUE; finish_flag = TRUE; preWriteTime = timeGet (); result = pingpong_PP_quit_msgDataWriter_write (PP_quit_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; default: printf("Invalid topic-id\n"); exit(1); } if (!terminate) { roundTripTime = preWriteTime; add_stats (&write_access, 1E6 * timeToReal (timeSub (postWriteTime, preWriteTime))); /* * Wait for response, calculate timing, and send another data if not ready */ while (!(timeout_flag || finish_flag)) { conditionList = DDS_ConditionSeq__alloc(); result = DDS_WaitSet_wait (w, conditionList, &wait_timeout); if (conditionList) { imax = conditionList->_length; if (imax != 0) { for (i = 0; i < imax; i++) { if (conditionList->_buffer[i] == exp_condition) { finish_flag = active_handler (nof_cycles); } else { printf ("PING: unexpected condition triggered: %x\n", (unsigned int)conditionList->_buffer[i]); } } } else { printf ("PING: TIMEOUT - message lost\n"); timeout_flag = TRUE; } DDS_free(conditionList); } else { printf ("PING: TIMEOUT - message lost\n"); timeout_flag = TRUE; } } } } if (!terminate) { finish_flag = FALSE; if (block == 0) { printf ("# PING PONG measurements (in us) \n"); printf ("# Executed at: %s", ctime(&clock)); printf ("# Roundtrip time [us] Write-access time [us] Read-access time [us]\n"); printf ("# Block Count mean min max Count mean min max Count mean min max\n"); } printf ("%6d %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f\n", block, roundtrip.count, roundtrip.average, roundtrip.min, roundtrip.max, write_access.count, write_access.average, write_access.min, write_access.max, read_access.count, read_access.average, read_access.min, read_access.max); fflush (NULL); init_stats (&write_access, "write_access"); init_stats (&read_access, "read_access"); init_stats (&roundtrip, "round_trip"); } } result = DDS_Subscriber_delete_datareader (s, PP_min_reader); result = DDS_Publisher_delete_datawriter (p, PP_min_writer); result = DDS_Subscriber_delete_datareader (s, PP_seq_reader); result = DDS_Publisher_delete_datawriter (p, PP_seq_writer); result = DDS_Subscriber_delete_datareader (s, PP_string_reader); result = DDS_Publisher_delete_datawriter (p, PP_string_writer); result = DDS_Subscriber_delete_datareader (s, PP_fixed_reader); result = DDS_Publisher_delete_datawriter (p, PP_fixed_writer); result = DDS_Subscriber_delete_datareader (s, PP_array_reader); result = DDS_Publisher_delete_datawriter (p, PP_array_writer); result = DDS_Publisher_delete_datawriter (p, PP_quit_writer); result = DDS_DomainParticipant_delete_subscriber (dp, s); result = DDS_DomainParticipant_delete_publisher (dp, p); result = DDS_DomainParticipant_delete_topic (dp, PP_min_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_seq_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_string_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_fixed_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_array_topic); result = DDS_DomainParticipant_delete_topic (dp, PP_quit_topic); result = DDS_DomainParticipantFactory_delete_participant (dpf, dp); DDS_free (w); DDS_free (PP_min_dt); DDS_free (PP_seq_dt); DDS_free (PP_string_dt); DDS_free (PP_fixed_dt); DDS_free (PP_array_dt); DDS_free (PP_quit_dt); DDS_free (dpQos); DDS_free (tQos); DDS_free (dwQos); DDS_free (drQos); return 0; }
int main (int argc, char ** argv) #endif { /* Generic DDS entities */ DDS_DomainParticipant participant; DDS_Topic chatMessageTopic; DDS_Topic nameServiceTopic; DDS_Subscriber chatSubscriber; DDS_QueryCondition singleUser; DDS_ReadCondition newUser; DDS_StatusCondition leftUser; DDS_GuardCondition guard; DDS_WaitSet userLoadWS; DDS_LivelinessChangedStatus livChangStatus; /* QosPolicy holders */ DDS_TopicQos *setting_topic_qos; DDS_TopicQos *reliable_topic_qos; DDS_SubscriberQos *sub_qos; DDS_DataReaderQos *message_qos; /* DDS Identifiers */ DDS_DomainId_t domain = NULL; DDS_ReturnCode_t status; DDS_ConditionSeq *guardList = NULL; DDS_Duration_t timeout = DDS_DURATION_INFINITE; /* Type-specific DDS entities */ Chat_ChatMessageTypeSupport chatMessageTS; Chat_NameServiceTypeSupport nameServiceTS; Chat_NameServiceDataReader nameServer; Chat_ChatMessageDataReader loadAdmin; DDS_sequence_Chat_ChatMessage msgList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_sequence_Chat_NameService nsList = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_SampleInfoSeq infoSeq = { 0, 0, DDS_OBJECT_NIL, FALSE }; DDS_SampleInfoSeq infoSeq2 = { 0, 0, DDS_OBJECT_NIL, FALSE }; /* Others */ DDS_StringSeq args; int closed = 0; DDS_unsigned_long i, j; DDS_long prevCount = 0; char *partitionName; char *chatMessageTypeName = NULL; char *nameServiceTypeName = NULL; pthread_t tid; pthread_attr_t tattr; printf("Starting UserLoad example.\n"); fflush(stdout); /* Create a DomainParticipant (using the 'TheParticipantFactory' convenience macro). */ participant = DDS_DomainParticipantFactory_create_participant ( DDS_TheParticipantFactory, 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"); /* 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"); /* 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) + 1); checkHandle(sub_qos->partition.name._buffer[0], "DDS_string_alloc"); strcpy (sub_qos->partition.name._buffer[0], partitionName); /* Create a Subscriber for the UserLoad 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 NameService Topic (using the appropriate QoS). */ nameServer = DDS_Subscriber_create_datareader( chatSubscriber, nameServiceTopic, DDS_DATAREADER_QOS_USE_TOPIC_QOS, NULL, DDS_STATUS_MASK_NONE); checkHandle(nameServer, "DDS_Subscriber_create_datareader (NameService)"); /* Adapt the DataReaderQos for the ChatMessageDataReader to keep track of all messages. */ message_qos = DDS_DataReaderQos__alloc(); checkHandle(message_qos, "DDS_DataReaderQos__alloc"); status = DDS_Subscriber_get_default_datareader_qos(chatSubscriber, message_qos); checkStatus(status, "DDS_Subscriber_get_default_datareader_qos"); status = DDS_Subscriber_copy_from_topic_qos(chatSubscriber, message_qos, reliable_topic_qos); checkStatus(status, "DDS_Subscriber_copy_from_topic_qos"); message_qos->history.kind = DDS_KEEP_ALL_HISTORY_QOS; /* Create a DataReader for the ChatMessage Topic (using the appropriate QoS). */ loadAdmin = DDS_Subscriber_create_datareader( chatSubscriber, chatMessageTopic, message_qos, NULL, DDS_STATUS_MASK_NONE); checkHandle(loadAdmin, "DDS_Subscriber_create_datareader (ChatMessage)"); /* Initialize the Query Arguments. */ args._length = 1; args._maximum = 1; args._buffer = DDS_StringSeq_allocbuf(1); checkHandle(args._buffer, "DDS_StringSeq_allocbuf"); args._buffer[0] = DDS_string_alloc (12); /* Enough for maximum size numbers. */ checkHandle(args._buffer[0], "DDS_string_alloc"); sprintf(args._buffer[0], "%d", 0); /* Create a QueryCondition that will contain all messages with userID=ownID */ singleUser = DDS_DataReader_create_querycondition( loadAdmin, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE, "userID=%0", &args); checkHandle(singleUser, "DDS_DataReader_create_querycondition (singleUser Query)"); /* Create a ReadCondition that will contain new users only */ newUser = DDS_DataReader_create_readcondition( nameServer, DDS_NOT_READ_SAMPLE_STATE, DDS_NEW_VIEW_STATE, DDS_ALIVE_INSTANCE_STATE); checkHandle(newUser, "DDS_DataReader_create_readcondition (newUser)"); /* Obtain a StatusCondition that triggers only when a Writer changes Liveliness */ leftUser = DDS_DataReader_get_statuscondition(loadAdmin); checkHandle(leftUser, "DDS_DataReader_get_statuscondition"); status = DDS_StatusCondition_set_enabled_statuses(leftUser, DDS_LIVELINESS_CHANGED_STATUS); checkStatus(status, "DDS_StatusCondition_set_enabled_statuses"); /* Create a bare guard which will be used to close the room */ escape = DDS_GuardCondition__alloc(); checkHandle(escape, "DDS_GuardCondition__alloc"); /* Create a waitset and add the ReadConditions */ userLoadWS = DDS_WaitSet__alloc(); checkHandle(userLoadWS, "DDS_WaitSet__alloc"); status = DDS_WaitSet_attach_condition(userLoadWS, newUser); checkStatus(status, "DDS_WaitSet_attach_condition (newUser)"); status = DDS_WaitSet_attach_condition(userLoadWS, leftUser); checkStatus(status, "DDS_WaitSet_attach_condition (leftUser)"); status = DDS_WaitSet_attach_condition(userLoadWS, escape); checkStatus(status, "DDS_WaitSet_attach_condition (escape)"); /* Initialize and pre-allocate the GuardList used to obtain the triggered Conditions. */ guardList = DDS_ConditionSeq__alloc(); checkHandle(guardList, "DDS_ConditionSeq__alloc"); guardList->_maximum = 3; guardList->_length = 0; guardList->_buffer = DDS_ConditionSeq_allocbuf(3); checkHandle(guardList->_buffer, "DDS_ConditionSeq_allocbuf"); /* Remove all known Users that are not currently active. */ status = Chat_NameServiceDataReader_take( nameServer, &nsList, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_NOT_ALIVE_INSTANCE_STATE); checkStatus(status, "Chat_NameServiceDataReader_take"); status = Chat_NameServiceDataReader_return_loan(nameServer, &nsList, &infoSeq); checkStatus(status, "Chat_NameServiceDataReader_return_loan"); /* Start the sleeper thread. */ pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); pthread_create (&tid, &tattr, delayedEscape, NULL); pthread_attr_destroy(&tattr); while (!closed) { /* Wait until at least one of the Conditions in the waitset triggers. */ status = DDS_WaitSet_wait(userLoadWS, guardList, &timeout); checkStatus(status, "DDS_WaitSet_wait"); /* Walk over all guards to display information */ for (i = 0; i < guardList->_length; i++) { guard = guardList->_buffer[i]; if (guard == newUser) { /* The newUser ReadCondition contains data */ status = Chat_NameServiceDataReader_read_w_condition( nameServer, &nsList, &infoSeq, DDS_LENGTH_UNLIMITED, newUser); checkStatus(status, "Chat_NameServiceDataReader_read_w_condition"); for (j = 0; j < nsList._length; j++) { printf ("New user: %s\n", nsList._buffer[j].name); } status = Chat_NameServiceDataReader_return_loan(nameServer, &nsList, &infoSeq); checkStatus(status, "Chat_NameServiceDataReader_return_loan"); } else if (guard == leftUser) { /* Some liveliness has changed (either a DataWriter joined or a DataWriter left) */ status = DDS_DataReader_get_liveliness_changed_status(loadAdmin, &livChangStatus); checkStatus(status, "DDS_DataReader_get_liveliness_changed_status"); if (livChangStatus.alive_count < prevCount) { /* A user has left the ChatRoom, since a DataWriter lost its liveliness */ /* Take the effected users so tey will not appear in the list later on. */ status = Chat_NameServiceDataReader_take( nameServer, &nsList, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE); checkStatus(status, "Chat_NameServiceDataReader_take"); for (j = 0; j < nsList._length; j++) { /* re-apply query arguments */ sprintf(args._buffer[0], "%d", nsList._buffer[j].userID); status = DDS_QueryCondition_set_query_parameters(singleUser, &args); checkStatus(status, "DDS_QueryCondition_set_query_parameters"); /* Read this users history */ status = Chat_ChatMessageDataReader_take_w_condition( loadAdmin, &msgList, &infoSeq2, DDS_LENGTH_UNLIMITED, singleUser); checkStatus(status, "Chat_ChatMessageDataReader_take_w_condition"); /* Display the user and his history */ printf ( "Departed user %s has sent %d messages\n", nsList._buffer[j].name, msgList._length); status = Chat_ChatMessageDataReader_return_loan(loadAdmin, &msgList, &infoSeq2); checkStatus(status, "Chat_ChatMessageDataReader_return_loan"); } status = Chat_NameServiceDataReader_return_loan(nameServer, &nsList, &infoSeq); checkStatus(status, "Chat_NameServiceDataReader_return_loan"); } prevCount = livChangStatus.alive_count; } else if (guard == escape) { printf ("UserLoad has terminated.\n"); closed = 1; } else { assert(0); }; } /* for */ } /* while (!closed) */ /* Remove all Conditions from the WaitSet. */ status = DDS_WaitSet_detach_condition(userLoadWS, escape); checkStatus(status, "DDS_WaitSet_detach_condition (escape)"); status = DDS_WaitSet_detach_condition(userLoadWS, leftUser); checkStatus(status, "DDS_WaitSet_detach_condition (leftUser)"); status = DDS_WaitSet_detach_condition(userLoadWS, newUser); checkStatus(status, "DDS_WaitSet_detach_condition (newUser)"); /* Free all resources */ DDS_free(guardList); DDS_free(args._buffer); DDS_free(userLoadWS); DDS_free(escape); DDS_free(setting_topic_qos); DDS_free(reliable_topic_qos); DDS_free(nameServiceTypeName); DDS_free(chatMessageTypeName); DDS_free(nameServiceTS); DDS_free(chatMessageTS); status = DDS_DomainParticipant_delete_contained_entities(participant); checkStatus(status, "DDS_DomainParticipant_delete_contained_entities"); status = DDS_DomainParticipantFactory_delete_participant( DDS_TheParticipantFactory, participant); checkStatus(status, "DDS_DomainParticipantFactory_delete_participant"); return 0; }
void do_chat (DDS_DataWriter dw) { ChatMsg_t m; DDS_InstanceHandle_t h; char buf [256]; #if !defined (NUTTX_RTOS) tty_init (); #endif DDS_Handle_attach (tty_stdin, POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL, tty_input, NULL); printf ("Welcome to the ROS 2.0 DDS chatroom.\r\n"); printf ("Anything you type will be sent to all chatroom attendees.\r\n"); printf (" (Please write messages of less than 255 characters).\r\n"); printf ("Type '!help' for chatroom options.\r\n"); m.chatroom = chatroom; m.from = user_name; h = 0; while (!aborting) { #if defined (NUTTX_RTOS) /* Take into account that fgets reads the "\n" character at the end of each line. Code should consider this aspect in every case */ fgets(buf, 256, stdin); #else tty_gets (sizeof (buf), buf, 0, 1); #endif if (buf [0] == '!') { #if defined (NUTTX_RTOS) if (!strcmp (buf + 1, "quit\n") || (buf [1] == 'q' && buf [2] == '\n')) { #else if (!strcmp (buf + 1, "quit") || (buf [1] == 'q' && buf [2] == '\0')) { #endif aborting = 1; break; } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "list\n")) #else else if (!strcmp (buf + 1, "list")) #endif printf ("Attendees:\r\n\t%s\r\n", user_name); #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "user\n", 4)) { #else else if (!memcmp (buf + 1, "user", 4)) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } strcpy (user_name, buf + 6); printf ("You are now: %s\r\n", user_name); } #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "room\n", 4)) { #else else if (!memcmp (buf + 1, "room", 4)) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } strcpy (chatroom, buf + 6); printf ("Switched to chatroom: %s\r\n", chatroom); } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "info\n")) #else else if (!strcmp (buf + 1, "info")) #endif printf ("Chatroom: %s, Username: %s\r\n", chatroom, user_name); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "busy\n")) #else else if (!strcmp (buf + 1, "busy")) #endif ChatMsg_signal (dw, h, 0); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "away\n")) { #else else if (!strcmp (buf + 1, "away")) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "help\n") || (buf [1] == 'h' && buf [2] == '\n\0') || (buf [1] == '?' && buf [2] == '\n\0')) { #else else if (!strcmp (buf + 1, "help") || (buf [1] == 'h' && buf [2] == '\0') || (buf [1] == '?' && buf [2] == '\0')) { #endif printf ("Commands:\r\n"); printf (" !room <room_name> -> set the chatroom name.\r\n"); printf (" !user <user_name> -> set the user name.\r\n"); printf (" !list -> list the attendees.\r\n"); printf (" !info -> show chatroom and user.\r\n"); printf (" !busy -> momentarily not involved.\r\n"); printf (" !away -> gone away.\r\n"); printf (" !help or !h or !? -> Show this info.\r\n"); printf (" !quit or !q -> Quit the chatroom.\r\n"); printf (" !!<command> -> DDS debug command.\r\n"); /* printf (" !$<command> -> Shell command.\r\n"); */ } else if (buf [1] == '!') DDS_Debug_command (buf + 2); /* else if (buf [1] == '$') system (buf + 2); */ else printf ("?%s\r\n", buf + 1); continue; } if (!h) h = ChatMsg_register (dw, &m); m.message = buf; ChatMsg_write (dw, &m, h); } } void read_msg (DDS_DataReaderListener *l, DDS_DataReader dr) { ChatMsg_t msg; DDS_InstanceStateKind kind; int valid; DDS_ReturnCode_t ret; ARG_NOT_USED (l) memset (&msg, 0, sizeof (msg)); ret = ChatMsg_read_or_take (dr, &msg, DDS_NOT_READ_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE, 1, &valid, &kind); if (ret == DDS_RETCODE_OK) do { #ifndef DISPLAY_SELF if (!strcmp (msg.from, user_name) && !strcmp (msg.chatroom, chatroom)) break; #endif if (valid) printf ("%s: %s\r\n", msg.from, msg.message); else if (kind == DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE) printf ("%s is busy!\r\n", msg.from); else if (kind == DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE) printf ("%s has left!\r\n", msg.from); } while (0); ChatMsg_cleanup (&msg); } #ifdef WAITSETS static void *chat_reader (void *args) { DDS_DynamicDataReader dr; DDS_WaitSet ws; DDS_SampleStateMask ss = DDS_NOT_READ_SAMPLE_STATE; DDS_ViewStateMask vs = DDS_ANY_VIEW_STATE; DDS_InstanceStateMask is = DDS_ANY_INSTANCE_STATE; DDS_ReadCondition rc; DDS_ConditionSeq conds = DDS_SEQ_INITIALIZER (DDS_Condition); DDS_Duration_t to; DDS_ReturnCode_t ret; dr = args; ws = DDS_WaitSet__alloc (); if (!ws) fatal ("Unable to allocate a WaitSet!"); if (verbose) printf ("DDS Waitset allocated.\r\n"); rc = DDS_DataReader_create_readcondition (dr, ss, vs, is); if (!rc) fatal ("DDS_DataReader_create_readcondition () returned an error!"); if (verbose) printf ("DDS Readcondition created.\r\n"); ret = DDS_WaitSet_attach_condition (ws, rc); if (ret) fatal ("Unable to attach condition to a WaitSet!"); while (!aborting) { to.sec = 0; to.nanosec = 200000000; /* Timeout after 200ms. */ ret = DDS_WaitSet_wait (ws, &conds, &to); if (ret == DDS_RETCODE_TIMEOUT) continue; read_msg (NULL, dr); } ret = DDS_WaitSet_detach_condition (ws, rc); if (ret) fatal ("Unable to detach condition from WaitSet (%s)!", DDS_error (ret)); DDS_WaitSet__free (ws); return (NULL); } static void start_chat_reader (DDS_DynamicDataReader dr) { thread_create (rt, chat_reader, dr); } static void stop_chat_reader (DDS_DynamicDataReader dr) { ARG_NOT_USED (dr) thread_wait (rt, NULL); } #else static DDS_DataReaderListener msg_listener = { NULL, /* Sample rejected. */ NULL, /* Liveliness changed. */ NULL, /* Requested Deadline missed. */ NULL, /* Requested incompatible QoS. */ read_msg, /* Data available. */ NULL, /* Subscription matched. */ NULL, /* Sample lost. */ NULL /* Cookie */ }; #endif #ifdef DDS_SECURITY #define fail_unless assert static void enable_security (void) { DDS_Credentials credentials; DDS_ReturnCode_t error; #ifdef MSECPLUG_WITH_SECXML /*int dhandle, thandle;*/ #endif error = DDS_SP_set_policy (); if (error) fatal ("DDS_SP_set_policy() returned error (%s)!", DDS_error (error)); #ifdef MSECPLUG_WITH_SECXML if (DDS_SP_parse_xml ("security.xml")) fatal ("SP: no DDS security rules in 'security.xml'!\r\n"); #else DDS_SP_add_domain(); if (!realm_name) DDS_SP_add_participant (); else DDS_SP_set_participant_access (DDS_SP_add_participant (), strcat(realm_name, "*"), 2, 0); #endif if (!cert_path || !key_path) fatal ("Error: you must provide a valid certificate path and a valid private key path\r\n"); if (engine_id) { DDS_SP_init_engine (engine_id, init_engine_fs); credentials.credentialKind = DDS_ENGINE_BASED; credentials.info.engine.engine_id = engine_id; credentials.info.engine.cert_id = cert_path; credentials.info.engine.priv_key_id = key_path; } else { credentials.credentialKind = DDS_FILE_BASED; credentials.info.filenames.private_key_file = key_path; credentials.info.filenames.certificate_chain_file = cert_path; } error = DDS_Security_set_credentials ("Technicolor Chatroom", &credentials); }
int OSPL_MAIN (int argc, char *argv[]) { DDS_sequence_ListenerData_Msg* message_seq = DDS_sequence_ListenerData_Msg__alloc(); DDS_SampleInfoSeq* message_infoSeq = DDS_SampleInfoSeq__alloc(); DDS_Subscriber message_Subscriber; DDS_DataReader message_DataReader; DDS_WaitSet waitSet; DDS_ConditionSeq* guardList = NULL; struct DDS_DataReaderListener *message_Listener; DDS_Duration_t timeout = { 0, 200000000 }; struct Listener_data* Listener_data; DDS_GuardCondition guardCondition = DDS_GuardCondition__alloc(); int count = 0; DDS_StatusMask mask; // Create DDS DomainParticipant createParticipant("Listener example"); // Register the Topic's type in the DDS Domain. g_MessageTypeSupport = ListenerData_MsgTypeSupport__alloc(); checkHandle(g_MessageTypeSupport, "ListenerData_MsgTypeSupport__alloc"); registerMessageType(g_MessageTypeSupport); // Create the Topic's in the DDS Domain. g_MessageTypeName = ListenerData_MsgTypeSupport_get_type_name(g_MessageTypeSupport); g_MessageTopic = createTopic("ListenerData_Msg", g_MessageTypeName); DDS_free(g_MessageTypeName); DDS_free(g_MessageTypeSupport); // Create the Subscriber's in the DDS Domain. message_Subscriber = createSubscriber(); // Request a Reader from the the Subscriber. message_DataReader = createDataReader(message_Subscriber, g_MessageTopic); /* Allocate the DataReaderListener interface. */ message_Listener = DDS_DataReaderListener__alloc(); checkHandle(message_Listener, "DDS_DataReaderListener__alloc"); Listener_data = malloc(sizeof(struct Listener_data)); checkHandle(Listener_data, "malloc"); Listener_data->guardCondition = &guardCondition; Listener_data->message_DataReader = &message_DataReader; Listener_data->isClosed = &isClosed; message_Listener->listener_data = Listener_data; message_Listener->on_data_available = on_data_available; message_Listener->on_requested_deadline_missed = on_requested_deadline_missed; mask = DDS_DATA_AVAILABLE_STATUS | DDS_REQUESTED_DEADLINE_MISSED_STATUS; g_status = DDS_DataReader_set_listener(message_DataReader, message_Listener, mask); checkStatus(g_status, "DDS_DataReader_set_listener"); // WaitSet is used to avoid spinning in the loop below. waitSet = DDS_WaitSet__alloc(); checkHandle(waitSet, "DDS_WaitSet__alloc"); g_status = DDS_WaitSet_attach_condition(waitSet, guardCondition); checkStatus(g_status, "DDS_WaitSet_attach_condition (readCondition)"); // Initialize and pre-allocate the GuardList used to obtain the triggered Conditions. guardList = DDS_ConditionSeq__alloc(); checkHandle(guardList, "DDS_ConditionSeq__alloc"); guardList->_maximum = 1; guardList->_length = 0; guardList->_buffer = DDS_ConditionSeq_allocbuf(1); checkHandle(guardList->_buffer, "DDS_ConditionSeq_allocbuf"); printf("\n=== [ListenerDataSubscriber] Ready..."); isClosed = FALSE; do { g_status = DDS_WaitSet_wait(waitSet, guardList, &timeout); if(g_status != DDS_RETCODE_TIMEOUT) { checkStatus(g_status, "DDS_WaitSet_wait"); } else { printf("\n=== [ListenerDataSubscriber] (timeout)"); } g_status = DDS_GuardCondition_set_trigger_value(guardCondition, FALSE); checkStatus(g_status, "DDS_GuardCondition_set_trigger_value"); ++ count; } while( isClosed == FALSE && count < 1500 ); printf("\n\n=== [ListenerDataSubscriber] isClosed"); // Cleanup DDS from the created Entities. deleteDataReader(message_Subscriber, message_DataReader); deleteSubscriber(message_Subscriber); deleteTopic(g_MessageTopic); deleteParticipant(); // Cleanup C allocations // Recursively free the instances sequence using the OpenSplice API. DDS_free(message_seq); DDS_free(message_infoSeq); free(Listener_data); // Print out an empty line, just to avoid the shell writing on the same line as our last output. printf("\n"); return 0; }
int OSPL_MAIN (int argc, char ** argv) #endif { DDS_ConditionSeq *conditionList; DDS_WaitSet w; DDS_DomainParticipantQos *dpQos; DDS_TopicQos *tQos; DDS_PublisherQos *pQos; DDS_DataWriterQos *dwQos; DDS_SubscriberQos *sQos; DDS_DataReaderQos *drQos; DDS_Condition exp_condition = NULL; pong_handler *active_handler = NULL; DDS_Duration_t wait_timeout = {3,0}; DDS_boolean finish_flag = FALSE; DDS_boolean timeout_flag = FALSE; DDS_boolean terminate = FALSE; DDS_ReturnCode_t result; int imax = 1; int i; unsigned int block; printf ("Starting ping example\n"); fflush(stdout); /* * init timing statistics */ init_stats (&roundtrip, "round_trip"); init_stats (&write_access, "write_access"); init_stats (&read_access, "read_access"); /* * Evaluate cmdline arguments */ #ifdef INTEGRITY nof_blocks = 100; nof_cycles = 100; #if defined (PING1) topic_id = 'm'; #elif defined (PING2) topic_id = 'q'; #elif defined (PING3) topic_id = 's'; #elif defined (PING4) topic_id = 'f'; #elif defined (PING5) topic_id = 'b'; #elif defined (PING6) nof_blocks = 1; nof_cycles = 10; topic_id = 't'; #endif write_partition = "PongRead"; read_partition = "PongWrite"; #else if (argc != 1) { if (argc != 6) { printf ("Invalid.....\n Usage: %s [blocks blocksize topic_id WRITE_PARTITION READ_PARTITION]\n", argv[0]); exit (1); } nof_blocks = atoi (argv[1]); nof_cycles = atoi (argv[2]); topic_id = argv[3][0]; write_partition = argv[4]; read_partition = argv[5]; } #endif #ifdef _WIN32 init_clock(); #endif /* * Create WaitSet */ w = DDS_WaitSet__alloc (); /* * Initialize Qos variables */ dpQos = DDS_DomainParticipantQos__alloc(); tQos = DDS_TopicQos__alloc(); pQos = DDS_PublisherQos__alloc(); dwQos = DDS_DataWriterQos__alloc(); sQos = DDS_SubscriberQos__alloc(); drQos = DDS_DataReaderQos__alloc(); /* * Initialize condition list */ conditionList = NULL; /* * Create participant */ dpf = DDS_DomainParticipantFactory_get_instance (); dp = DDS_DomainParticipantFactory_create_participant (dpf, myDomain, DDS_PARTICIPANT_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); if (dp == DDS_HANDLE_NIL) { printf ("%s PING: ERROR - Splice Daemon not running", argv[0]); exit (1); } /* * Create PING publisher */ DDS_DomainParticipant_get_default_publisher_qos (dp, pQos); pQos->partition.name._length = 1; pQos->partition.name._maximum = 1; pQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); pQos->partition.name._buffer[0] = DDS_string_dup (write_partition); p = DDS_DomainParticipant_create_publisher (dp, pQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (pQos); /* * Create PONG subscriber */ DDS_DomainParticipant_get_default_subscriber_qos (dp, sQos); sQos->partition.name._length = 1; sQos->partition.name._maximum = 1; sQos->partition.name._buffer = DDS_StringSeq_allocbuf (1); sQos->partition.name._buffer[0] = DDS_string_dup (read_partition); s = DDS_DomainParticipant_create_subscriber (dp, sQos, NULL, DDS_STATUS_MASK_NONE); DDS_free (sQos); /* * PP_min_msg */ /* Create Topic */ PP_min_dt = pingpong_PP_min_msgTypeSupport__alloc (); pingpong_PP_min_msgTypeSupport_register_type (PP_min_dt, dp, "pingpong::PP_min_msg"); PP_min_topic = DDS_DomainParticipant_create_topic (dp, "PP_min_topic", "pingpong::PP_min_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); DDS_Publisher_get_default_datawriter_qos(p, dwQos); dwQos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS; dwQos->history.kind = DDS_KEEP_ALL_HISTORY_QOS; /* Create datawriter */ PP_min_writer = DDS_Publisher_create_datawriter (p, PP_min_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_min_reader = DDS_Subscriber_create_datareader (s, PP_min_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_min_sc = DDS_DataReader_get_statuscondition (PP_min_reader); DDS_StatusCondition_set_enabled_statuses (PP_min_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_min_sc); /* * PP_seq_msg */ /* Create Topic */ PP_seq_dt = pingpong_PP_seq_msgTypeSupport__alloc (); pingpong_PP_seq_msgTypeSupport_register_type (PP_seq_dt, dp, "pingpong::PP_seq_msg"); PP_seq_topic = DDS_DomainParticipant_create_topic (dp, "PP_seq_topic", "pingpong::PP_seq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_seq_writer = DDS_Publisher_create_datawriter (p, PP_seq_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_seq_reader = DDS_Subscriber_create_datareader (s, PP_seq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_seq_sc = DDS_DataReader_get_statuscondition (PP_seq_reader); DDS_StatusCondition_set_enabled_statuses (PP_seq_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_seq_sc); /* * PP_string_msg */ /* Create Topic */ PP_string_dt = pingpong_PP_string_msgTypeSupport__alloc (); pingpong_PP_string_msgTypeSupport_register_type (PP_string_dt, dp, "pingpong::PP_string_msg"); PP_string_topic = DDS_DomainParticipant_create_topic (dp, "PP_string_topic", "pingpong::PP_string_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_string_writer = DDS_Publisher_create_datawriter (p, PP_string_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_string_reader = DDS_Subscriber_create_datareader (s, PP_string_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_string_sc = DDS_DataReader_get_statuscondition (PP_string_reader); DDS_StatusCondition_set_enabled_statuses (PP_string_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_string_sc); /* * PP_fixed_msg */ /* Create Topic */ PP_fixed_dt = pingpong_PP_fixed_msgTypeSupport__alloc (); pingpong_PP_fixed_msgTypeSupport_register_type (PP_fixed_dt, dp, "pingpong::PP_fixed_msg"); PP_fixed_topic = DDS_DomainParticipant_create_topic (dp, "PP_fixed_topic", "pingpong::PP_fixed_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_fixed_writer = DDS_Publisher_create_datawriter (p, PP_fixed_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_fixed_reader = DDS_Subscriber_create_datareader (s, PP_fixed_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_fixed_sc = DDS_DataReader_get_statuscondition (PP_fixed_reader); DDS_StatusCondition_set_enabled_statuses (PP_fixed_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_fixed_sc); /* * PP_array_msg */ /* Create Topic */ PP_array_dt = pingpong_PP_array_msgTypeSupport__alloc (); pingpong_PP_array_msgTypeSupport_register_type (PP_array_dt, dp, "pingpong::PP_array_msg"); PP_array_topic = DDS_DomainParticipant_create_topic (dp, "PP_array_topic", "pingpong::PP_array_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_array_writer = DDS_Publisher_create_datawriter (p, PP_array_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_array_reader = DDS_Subscriber_create_datareader (s, PP_array_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_array_sc = DDS_DataReader_get_statuscondition (PP_array_reader); DDS_StatusCondition_set_enabled_statuses (PP_array_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_array_sc); /* * PP_bseq_msg */ /* Create Topic */ PP_bseq_dt = pingpong_PP_bseq_msgTypeSupport__alloc (); pingpong_PP_bseq_msgTypeSupport_register_type (PP_bseq_dt, dp, "pingpong::PP_bseq_msg"); PP_bseq_topic = DDS_DomainParticipant_create_topic (dp, "PP_bseq_topic", "pingpong::PP_bseq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_bseq_writer = DDS_Publisher_create_datawriter (p, PP_bseq_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Create datareader */ PP_bseq_reader = DDS_Subscriber_create_datareader (s, PP_bseq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Add datareader statuscondition to waitset */ PP_bseq_sc = DDS_DataReader_get_statuscondition (PP_bseq_reader); DDS_StatusCondition_set_enabled_statuses (PP_bseq_sc, DDS_DATA_AVAILABLE_STATUS); DDS_WaitSet_attach_condition (w, PP_bseq_sc); /* * PP_quit_msg */ /* Create Topic */ PP_quit_dt = pingpong_PP_quit_msgTypeSupport__alloc (); pingpong_PP_quit_msgTypeSupport_register_type (PP_quit_dt, dp, "pingpong::PP_quit_msg"); PP_quit_topic = DDS_DomainParticipant_create_topic (dp, "PP_quit_topic", "pingpong::PP_quit_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE); /* Create datawriter */ PP_quit_writer = DDS_Publisher_create_datawriter (p, PP_quit_topic, dwQos, NULL, DDS_STATUS_MASK_NONE); /* Fr: workarround for ticket dds1712 */ conditionList = DDS_ConditionSeq__alloc(); assert(conditionList); DDS_WaitSet_wait (w, conditionList, &wait_timeout); DDS_free(conditionList); for (block = 0; block < nof_blocks && !terminate ; block++) { while (!finish_flag) { /* * Send Initial message */ timeout_flag = FALSE; switch(topic_id) { case 'm': { /* printf ("PING: sending initial ping_min\n"); */ pingpong_PP_min_msg *PPdata = pingpong_PP_min_msg__alloc (); exp_condition = PP_min_sc; active_handler = &PP_min_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); pingpong_PP_min_msgDataWriter_write (PP_min_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'q': { /* printf ("PING: sending initial ping_seq\n"); */ pingpong_PP_seq_msg *PPdata = pingpong_PP_seq_msg__alloc (); exp_condition = PP_seq_sc; active_handler = &PP_seq_handler; PPdata->count = 0; PPdata->block = block; { int i = 0; PPdata->payload._buffer = pingpong_seq_char_allocbuf(SEQ_PAYLOAD_SIZE); PPdata->payload._length = SEQ_PAYLOAD_SIZE; PPdata->payload._maximum = SEQ_PAYLOAD_SIZE; for (i=0; i<SEQ_PAYLOAD_SIZE; i++) { PPdata->payload._buffer[i] = (char)i; } } preWriteTime = timeGet (); pingpong_PP_seq_msgDataWriter_write (PP_seq_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 's': { /* printf ("PING: sending initial ping_string\n"); */ pingpong_PP_string_msg *PPdata = pingpong_PP_string_msg__alloc (); exp_condition = PP_string_sc; active_handler = &PP_string_handler; PPdata->count = 0; PPdata->block = block; PPdata->a_string = DDS_string_dup ("a_string"); preWriteTime = timeGet (); pingpong_PP_string_msgDataWriter_write (PP_string_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'f': { /* printf ("PING: sending initial ping_fixed\n"); */ pingpong_PP_fixed_msg *PPdata = pingpong_PP_fixed_msg__alloc (); exp_condition = PP_fixed_sc; active_handler = &PP_fixed_handler; PPdata->count = 0; PPdata->block = block; PPdata->a_bstring = DDS_string_dup ("a_bstring"); preWriteTime = timeGet (); pingpong_PP_fixed_msgDataWriter_write (PP_fixed_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'a': { /* printf ("PING: sending initial ping_array\n"); */ pingpong_PP_array_msg *PPdata = pingpong_PP_array_msg__alloc (); exp_condition = PP_array_sc; active_handler = &PP_array_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); pingpong_PP_array_msgDataWriter_write (PP_array_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 'b': { /* printf ("PING: sending initial ping_bseq_msg\n"); */ pingpong_PP_bseq_msg *PPdata = pingpong_PP_bseq_msg__alloc (); exp_condition = PP_bseq_sc; active_handler = &PP_bseq_handler; PPdata->count = 0; PPdata->block = block; preWriteTime = timeGet (); pingpong_PP_bseq_msgDataWriter_write (PP_bseq_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); DDS_free (PPdata); } break; case 't': { /* printf ("PING: sending initial ping_quit\n"); */ pingpong_PP_quit_msg *PPdata = pingpong_PP_quit_msg__alloc(); PPdata->quit = TRUE; terminate = TRUE; finish_flag = TRUE; sleep(1); preWriteTime = timeGet (); pingpong_PP_quit_msgDataWriter_write (PP_quit_writer, PPdata, DDS_HANDLE_NIL); postWriteTime = timeGet (); sleep(1); DDS_free (PPdata); } break; default: printf("Invalid topic-id\n"); exit(1); } if (!terminate) { roundTripTime = preWriteTime; add_stats (&write_access, 1E6 * timeToReal (timeSub (postWriteTime, preWriteTime))); /* * Wait for response, calculate timing, and send another data if not ready */ while (!(timeout_flag || finish_flag)) { conditionList = DDS_ConditionSeq__alloc(); result = DDS_WaitSet_wait (w, conditionList, &wait_timeout); if(result == DDS_RETCODE_OK || result == DDS_RETCODE_NO_DATA || result == DDS_RETCODE_TIMEOUT) { if (conditionList) { imax = conditionList->_length; if (imax != 0) { for (i = 0; i < imax; i++) { if (conditionList->_buffer[i] == exp_condition) { finish_flag = active_handler (nof_cycles); } else { printf ("PING: unexpected condition triggered: %lx\n", (unsigned long)conditionList->_buffer[i]); } } } else { printf ("PING: TIMEOUT - message lost\n"); timeout_flag = TRUE; } DDS_free(conditionList); } else { printf ("PING: TIMEOUT - message lost\n"); timeout_flag = TRUE; } } else { printf ("PING: Waitset wait failed (code %d), terminating.\n", result); finish_flag = TRUE; terminate = TRUE; } } } } if (!terminate) { finish_flag = FALSE; if (block == 0) { printf ("# PING PONG measurements (in us) \n"); printf ("# Roundtrip time [us] Write-access time [us] Read-access time [us]\n"); printf ("# Block Count mean min max Count mean min max Count mean min max\n"); } printf ("%6d %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f\n", block, roundtrip.count, roundtrip.average, roundtrip.min, roundtrip.max, write_access.count, write_access.average, write_access.min, write_access.max, read_access.count, read_access.average, read_access.min, read_access.max); fflush (stdout); init_stats (&write_access, "write_access"); init_stats (&read_access, "read_access"); init_stats (&roundtrip, "round_trip"); } } DDS_Subscriber_delete_datareader (s, PP_min_reader); DDS_Publisher_delete_datawriter (p, PP_min_writer); DDS_Subscriber_delete_datareader (s, PP_seq_reader); DDS_Publisher_delete_datawriter (p, PP_seq_writer); DDS_Subscriber_delete_datareader (s, PP_string_reader); DDS_Publisher_delete_datawriter (p, PP_string_writer); DDS_Subscriber_delete_datareader (s, PP_fixed_reader); DDS_Publisher_delete_datawriter (p, PP_fixed_writer); DDS_Subscriber_delete_datareader (s, PP_array_reader); DDS_Publisher_delete_datawriter (p, PP_array_writer); DDS_Subscriber_delete_datareader (s, PP_bseq_reader); DDS_Publisher_delete_datawriter (p, PP_bseq_writer); DDS_Publisher_delete_datawriter (p, PP_quit_writer); DDS_DomainParticipant_delete_subscriber (dp, s); DDS_DomainParticipant_delete_publisher (dp, p); DDS_DomainParticipant_delete_topic (dp, PP_min_topic); DDS_DomainParticipant_delete_topic (dp, PP_seq_topic); DDS_DomainParticipant_delete_topic (dp, PP_string_topic); DDS_DomainParticipant_delete_topic (dp, PP_fixed_topic); DDS_DomainParticipant_delete_topic (dp, PP_array_topic); DDS_DomainParticipant_delete_topic (dp, PP_bseq_topic); DDS_DomainParticipant_delete_topic (dp, PP_quit_topic); DDS_DomainParticipantFactory_delete_participant (dpf, dp); DDS_free (w); DDS_free (PP_min_dt); DDS_free (PP_seq_dt); DDS_free (PP_string_dt); DDS_free (PP_fixed_dt); DDS_free (PP_array_dt); DDS_free (PP_bseq_dt); DDS_free (PP_quit_dt); DDS_free (dpQos); DDS_free (tQos); DDS_free (dwQos); DDS_free (drQos); printf ("Completed ping example\n"); fflush(stdout); return 0; }
int OSPL_MAIN (int argc, char *argv[]) { DDS_sequence_WaitSetData_Msg* message_seq = DDS_sequence_WaitSetData_Msg__alloc(); DDS_SampleInfoSeq* message_infoSeq = DDS_SampleInfoSeq__alloc(); DDS_Subscriber message_Subscriber; DDS_DataReader message_DataReader; DDS_char* query_parameter = "Hello again"; DDS_char *query_string = "message=%0"; DDS_ReadCondition readCondition; DDS_QueryCondition queryCondition; DDS_StatusCondition statusCondition; DDS_WaitSet waitSet; DDS_GuardCondition escape; DDS_LivelinessChangedStatus livelinessChangedStatus; DDS_ConditionSeq *guardList = NULL; DDS_Duration_t timeout = { 20, 0 }; int count = 0; DDS_long previousLivelinessCount; c_bool isClosed = FALSE; c_bool isEscaped = FALSE; c_bool writerLeft = FALSE; unsigned long i, j; // Create DDS DomainParticipant createParticipant("WaitSet example"); // Register the Topic's type in the DDS Domain. g_MessageTypeSupport = WaitSetData_MsgTypeSupport__alloc(); checkHandle(g_MessageTypeSupport, "WaitSetData_MsgTypeSupport__alloc"); registerMessageType(g_MessageTypeSupport); // Create the Topic's in the DDS Domain. g_MessageTypeName = WaitSetData_MsgTypeSupport_get_type_name(g_MessageTypeSupport); g_MessageTopic = createTopic("WaitSetData_Msg", g_MessageTypeName); DDS_free(g_MessageTypeName); DDS_free(g_MessageTypeSupport); // Create the Subscriber's in the DDS Domain. message_Subscriber = createSubscriber(); // Request a Reader from the the Subscriber. message_DataReader = createDataReader(message_Subscriber, g_MessageTopic); // 1- Create a ReadCondition that will contain new Msg only. readCondition = DDS_DataReader_create_readcondition(message_DataReader, DDS_NOT_READ_SAMPLE_STATE, DDS_NEW_VIEW_STATE, DDS_ALIVE_INSTANCE_STATE); checkHandle(readCondition, "DDS_DataReader_create_readcondition (newUser)"); // 2- Create QueryCondition. queryCondition = createQueryCondition(message_DataReader, query_string, (DDS_char*) query_parameter); printf("=== [WaitSetDataSubscriber] Query : message = \"%s\"", query_parameter); // 3- Obtain a StatusCondition associated to a Writer // and that triggers only when the Writer changes Liveliness. statusCondition = DDS_DataReader_get_statuscondition(message_DataReader); checkHandle(statusCondition, "DDS_DataReader_get_statuscondition"); g_status = DDS_StatusCondition_set_enabled_statuses(statusCondition, DDS_LIVELINESS_CHANGED_STATUS); checkStatus(g_status, "DDS_StatusCondition_set_enabled_statuses"); // 4- Create a GuardCondition which will be used to close the subscriber. escape = DDS_GuardCondition__alloc(); checkHandle(escape, "DDS_GuardCondition__alloc"); // Create a waitset and add the 4 Conditions created above : // ReadCondition, QueryCondition, StatusCondition, GuardCondition. waitSet = DDS_WaitSet__alloc(); checkHandle(waitSet, "DDS_WaitSet__alloc"); g_status = DDS_WaitSet_attach_condition(waitSet, readCondition); checkStatus(g_status, "DDS_WaitSet_attach_condition (readCondition)"); g_status = DDS_WaitSet_attach_condition(waitSet, queryCondition); checkStatus(g_status, "DDS_WaitSet_attach_condition (queryCondition)"); g_status = DDS_WaitSet_attach_condition(waitSet, statusCondition); checkStatus(g_status, "DDS_WaitSet_attach_condition (statusCondition)"); g_status = DDS_WaitSet_attach_condition(waitSet, escape); checkStatus(g_status, "DDS_WaitSet_attach_condition (escape)"); // Initialize and pre-allocate the GuardList used to obtain the triggered Conditions. guardList = DDS_ConditionSeq__alloc(); checkHandle(guardList, "DDS_ConditionSeq__alloc"); guardList->_maximum = 4; guardList->_length = 0; guardList->_buffer = DDS_ConditionSeq_allocbuf(4); checkHandle(guardList->_buffer, "DDS_ConditionSeq_allocbuf"); printf("\n=== [WaitSetDataSubscriber] Ready ..."); // Used to store the livelinessChangedStatus.alive_count value (StatusCondition). previousLivelinessCount = 0; do { // Wait until at least one of the Conditions in the waitset triggers. g_status = DDS_WaitSet_wait(waitSet, guardList, &timeout); if (g_status == DDS_RETCODE_OK) { i = 0; do { if( guardList->_buffer[i] == statusCondition ) { // StatusCondition triggered. // Some liveliness has changed (either a DataWriter joined or a DataWriter left). // Check whether a new Writer appeared. g_status = DDS_DataReader_get_liveliness_changed_status(message_DataReader, &livelinessChangedStatus); checkStatus(g_status, "DDS_DataReader_get_liveliness_changed_status"); if( livelinessChangedStatus.alive_count > previousLivelinessCount ) { // a DataWriter joined. printf("\n\n!!! a MsgWriter joined"); g_status = DDS_StatusCondition_set_enabled_statuses(statusCondition, DDS_LIVELINESS_CHANGED_STATUS); checkStatus(g_status, "DDS_StatusCondition_set_enabled_statuses"); } else if( livelinessChangedStatus.alive_count < previousLivelinessCount ) { // A MsgWriter lost its liveliness. printf("\n\n!!! a MsgWriter lost its liveliness"); g_status = DDS_StatusCondition_set_enabled_statuses(statusCondition, DDS_LIVELINESS_CHANGED_STATUS); checkStatus(g_status, "DDS_StatusCondition_set_enabled_statuses"); writerLeft = TRUE; printf("\n === Triggering escape condition"); g_status = DDS_GuardCondition_set_trigger_value(escape, TRUE); checkStatus(g_status, "DDS_GuardCondition_set_trigger_value"); } else if ( livelinessChangedStatus.alive_count == previousLivelinessCount ) { // The status has changed, though alive_count is still zero, // this implies that both events have occurred, // and that the value is back to zero already. printf("\n\n!!! a MsgWriter joined\n"); printf("\n\n!!! a MsgWriter lost its liveliness\n"); writerLeft = TRUE; printf("\n === Triggering escape condition"); g_status = DDS_GuardCondition_set_trigger_value(escape, TRUE); checkStatus(g_status, "DDS_GuardCondition_set_trigger_value"); // NB: we do not need to activate this Condition anymore; // both events occurred. } // NB: Here we record the count a in order to compare it next time this condition triggers (?). previousLivelinessCount = livelinessChangedStatus.alive_count; } else if( guardList->_buffer[i] == readCondition ) { /* The newMsg ReadCondition contains data */ g_status = WaitSetData_MsgDataReader_read_w_condition(message_DataReader, message_seq, message_infoSeq, DDS_LENGTH_UNLIMITED, readCondition); checkStatus(g_status, "WaitSetData_MsgDataReader_read_w_condition"); for( j = 0; j < message_seq->_length ; j++ ) { printf("\n --- New message received ---"); if( message_infoSeq->_buffer[j].valid_data == TRUE ) { printf("\n userID : %d", message_seq->_buffer[j].userID); printf("\n Message : \"%s\"", message_seq->_buffer[j].message); } else { printf("\n Data is invalid!"); } } fflush(stdout); g_status = WaitSetData_MsgDataReader_return_loan(message_DataReader, message_seq, message_infoSeq); checkStatus(g_status, "WaitSetData_MsgDataReader_return_loan"); } else if( guardList->_buffer[i] == queryCondition ) { /* The queryCond QueryCondition contains data */ g_status = WaitSetData_MsgDataReader_take_w_condition(message_DataReader, message_seq, message_infoSeq, DDS_LENGTH_UNLIMITED, queryCondition); checkStatus(g_status, "WaitSetData_MsgDataReader_take_w_condition"); for( j = 0; j < message_seq->_length ; j++ ) { printf("\n\n --- message received (with QueryCOndition on message field) ---"); if( message_infoSeq->_buffer[j].valid_data == TRUE ) { printf("\n userID : %d", message_seq->_buffer[j].userID); printf("\n Message : \"%s\"", message_seq->_buffer[j].message); } else { printf("\n Data is invalid!"); } } fflush(stdout); g_status = WaitSetData_MsgDataReader_return_loan(message_DataReader, message_seq, message_infoSeq); checkStatus(g_status, "WaitSetData_MsgDataReader_return_loan"); } // This checks whether the Timeout Thread has resumed waiting. else if( guardList->_buffer[i] == escape ) { printf("\n escape condition triggered! - count = %d\n ", count); isEscaped = TRUE; g_status = DDS_GuardCondition_set_trigger_value(escape, FALSE); checkStatus(g_status, "DDS_GuardCondition_set_trigger_value"); } } while( ++i < guardList->_length ); } else if (g_status != DDS_RETCODE_TIMEOUT) { // DDS_RETCODE_TIMEOUT is considered as an error // only after it has occurred count times checkStatus(g_status, "DDS_WaitSet_wait"); } else { printf("!!! [INFO] WaitSet timedout - count = %d\n ", count); } ++count; isClosed = isEscaped && writerLeft; } while( isClosed == FALSE && count < 20); if (count >= 20) { printf( "*** Error : Timed out - count = %d ***\n", count); } /* Remove all Conditions from the WaitSet. */ g_status = DDS_WaitSet_detach_condition(waitSet, escape); checkStatus(g_status, "DDS_WaitSet_detach_condition (escape)"); g_status = DDS_WaitSet_detach_condition(waitSet, statusCondition); checkStatus(g_status, "DDS_WaitSet_detach_condition (statusCondition)"); g_status = DDS_WaitSet_detach_condition(waitSet, queryCondition); checkStatus(g_status, "DDS_WaitSet_detach_condition (queryCondition)"); g_status = DDS_WaitSet_detach_condition(waitSet, readCondition); checkStatus(g_status, "DDS_WaitSet_detach_condition (readCondition)"); // Cleanup DDS from the created Entities. deleteQueryCondition(message_DataReader, readCondition); deleteQueryCondition(message_DataReader, queryCondition); deleteDataReader(message_Subscriber, message_DataReader); deleteSubscriber(message_Subscriber); deleteTopic(g_MessageTopic); deleteParticipant(); // Cleanup C allocations // Recursively free the instances sequence using the OpenSplice API. DDS_free(guardList); DDS_free(message_seq); DDS_free(message_infoSeq); DDS_free(waitSet); DDS_free(escape); printf("\n"); return 0; }