static Endpoint_t *create_builtin_reader (Domain_t *dp, Builtin_Type_t type, const char *topic_name, const char *type_name) { TopicType_t *typep; Topic_t *tp; Reader_t *rp; DDS_TopicQos qos_data; typep = type_create (dp, type_name, NULL); if (!typep) return (NULL); typep->flags = EF_LOCAL | EF_BUILTIN; typep->index = type; tp = topic_create (&dp->participant, NULL, topic_name, type_name, NULL); if (!tp) return (NULL); tp->entity.flags |= EF_ENABLED | EF_BUILTIN | EF_NOT_IGNORED; qos_data = qos_def_topic_qos; qos_data.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS; qos_data.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS; tp->qos = qos_topic_new (&qos_data); if (!tp->qos) { topic_delete (&dp->participant, tp, NULL, NULL); return (NULL); } rp = DDS_Subscriber_create_datareader (dp->builtin_subscriber, (DDS_TopicDescription) tp, DDS_DATAREADER_QOS_USE_TOPIC_QOS, NULL, 0); if (!rp) { topic_delete (&dp->participant, tp, NULL, NULL); return (NULL); } dp->builtin_readers [type] = rp; #ifdef RTPS_USED if (rtps_used) disc_populate_builtin (dp, type); #endif return (&rp->r_ep); }
DDS_Topic DDS_DomainParticipant_create_topic (DDS_DomainParticipant dp, const char *topic_name, const char *type_name, const DDS_TopicQos *qos, const DDS_TopicListener *listener, DDS_StatusMask mask) { Topic_t *tp; int new_topic; ctrc_begind (DCPS_ID, DCPS_DP_C_TOP, &dp, sizeof (dp)); ctrc_contd (topic_name, strlen (topic_name) + 1); ctrc_contd (type_name, strlen (type_name) + 1); ctrc_contd (&qos, sizeof (qos)); ctrc_contd (&listener, sizeof (listener)); ctrc_contd (&mask, sizeof (mask)); ctrc_endd (); prof_start (dcps_create_topic); /* Get Domain Participant. */ if (!domain_ptr (dp, 1, NULL)) { log_printf (DCPS_ID, 0, "create_topic(%s): domain doesn't exist!\r\n", topic_name); return (NULL); } if (qos == DDS_TOPIC_QOS_DEFAULT) qos = &dp->def_topic_qos; else if (!qos_valid_topic_qos (qos)) { log_printf (DCPS_ID, 0, "create_topic(%s): invalid topic QoS!\r\n", topic_name); lock_release (dp->lock); return (NULL); } #ifdef DDS_SECURITY /* Check if security policy allows this topic. */ if (check_create_topic (dp->participant.p_permissions, topic_name, qos)) { log_printf (DCPS_ID, 0, "create_topic(%s): topic create not allowed!\r\n", topic_name); lock_release (dp->lock); return (NULL); } #endif /* New topic: create topic context. */ tp = topic_create (&dp->participant, NULL, topic_name, type_name, &new_topic); if (!tp) { log_printf (DCPS_ID, 0, "create_topic (%s): out of memory for topic!\r\n", topic_name); lock_release (dp->lock); return (NULL); } /* Set Qos fields appropriately. */ if (new_topic) tp->qos = qos_topic_new (qos); else if (tp->nlrefs == 1) /* First real QoS setting. */ qos_topic_update (&tp->qos, qos); /* Check if the supplied listener can be set on the topic. Ok, if no listener was previously set or the supplied listener is the same as the previously set listener. */ if (listener) { if (!new_topic && memcmp (&tp->listener, listener, sizeof (tp->listener))) log_printf (DCPS_ID, 0, "create_topic(%s): existing listener updated!\r\n", topic_name); tp->listener = *listener; } /* Check if the mask is the same. */ if (!new_topic && mask && mask != tp->mask) log_printf (DCPS_ID, 0, "create_topic(%s): existing mask updated!\r\n", topic_name); tp->mask = mask; lock_release (dp->lock); if (dp->autoenable) DDS_Topic_enable ((DDS_Topic) tp); prof_stop (dcps_create_topic, 1); return (tp); }
void sedp_topic_event (Reader_t *rp, NotificationType_t t) { Domain_t *dp = rp->r_subscriber->domain; Participant_t *pp; ChangeData_t change; DiscoveredTopicData *info = NULL, tinfo; Topic_t *tp; InfoType_t type; int error, new_node, valid_data = 0; const char *names [2]; if (t != NT_DATA_AVAILABLE) return; rp->r_status &= ~DDS_DATA_AVAILABLE_STATUS; for (;;) { if (info) { pid_topic_data_cleanup (&info); xfree (info); info = NULL; } /*dtrc_print0 ("SEDP-Topic: get samples ");*/ error = disc_get_data (rp, &change); if (error) { /*dtrc_print0 ("- none\r\n");*/ break; } /*dtrc_print1 ("- valid(%u)\r\n", change.kind);*/ if (change.kind != ALIVE) { /* error = hc_get_key (rp->r_cache, change.h, &tinfo, 0); if (error) continue; */ type = EI_DELETE; hc_inst_free (rp->r_cache, change.h); } else { type = EI_NEW; info = change.data; } pp = entity_participant (change.writer); if (!pp || /* Not found. */ pp == &dp->participant || /* Own sent info. */ entity_ignored (pp->p_flags)) { /* Ignored. */ hc_inst_free (rp->r_cache, change.h); continue; /* Filter out unneeded info. */ } /* Topic from remote participant. */ if (type == EI_DELETE) { /* TBD: Certified not to work correctly. */ tp = topic_lookup (pp, str_ptr (info.name)); if (!tp) { hc_inst_free (rp->r_cache, change.h); continue; /* If doesn't exist - no action. */ } names [0] = str_ptr (tp->name); names [1] = str_ptr (tp->type->type_name); } else { tp = topic_create (pp, NULL, names [0], names [1], &new_node); if (!tp) { hc_inst_free (rp->r_cache, change.h); continue; /* Can't create info -- just ignore. */ } if (!new_node) { if (entity_ignored (tp->entity.flags)) { hc_inst_free (rp->r_cache, change.h); continue; } type = EI_UPDATE; } names [0] = str_ptr (info->name); names [1] = str_ptr (info->type_name); } if (sedp_log) log_printf (SEDP_ID, 0, "SEDP: %s topic (%s/%s) from peer!\r\n", info_type_str [type], names [0], names [1]); sedp_topic_info (pp, tp, info, type); } if (info) { pid_topic_data_cleanup (info); xfree (info); } }