DDS_ReturnCode_t DDS_Subscriber_get_default_datareader_qos (DDS_Subscriber sp, DDS_DataReaderQos *qos) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_S_G_DR_QOS, &sp, sizeof (sp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!qos) { log_printf (DCPS_ID, 0, "get_default_datareader_qos: invalid parameters!\r\n"); return (DDS_RETCODE_BAD_PARAMETER); } if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); *qos = sp->def_reader_qos; lock_release (dp->lock); return (DDS_RETCODE_OK); }
DDS_ReturnCode_t DDS_Subscriber_set_default_datareader_qos (DDS_Subscriber sp, DDS_DataReaderQos *qos) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_S_S_DR_QOS, &sp, sizeof (sp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); if (qos == DDS_DATAREADER_QOS_DEFAULT) qos = (DDS_DataReaderQos *) &qos_def_reader_qos; else if (!qos_valid_reader_qos (qos)) { ret = DDS_RETCODE_BAD_PARAMETER; goto done; } sp->def_reader_qos = *qos; done: lock_release (dp->lock); return (ret); }
DDS_ReturnCode_t DDS_Subscriber_enable (DDS_Subscriber sp) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_printd (DCPS_ID, DCPS_S_ENABLE, &sp, sizeof (sp)); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); if ((dp->participant.p_flags & EF_ENABLED) == 0) { lock_release (dp->lock); return (DDS_RETCODE_NOT_ENABLED); } if ((sp->entity.flags & EF_ENABLED) == 0) { /* ... todo ... */ sp->entity.flags |= EF_ENABLED | EF_NOT_IGNORED; } lock_release (dp->lock); return (DDS_RETCODE_OK); }
DDS_StatusCondition DDS_Subscriber_get_statuscondition (DDS_Subscriber sp) { Domain_t *dp; StatusCondition_t *scp; ctrc_printd (DCPS_ID, DCPS_S_G_SCOND, &sp, sizeof (sp)); if (!subscriber_ptr (sp, NULL)) return (NULL); dp = domain_ptr (sp->domain, 1, NULL); if (!dp) return (NULL); scp = sp->condition; if (!scp) { scp = dcps_new_status_condition (); if (!scp) return (NULL); scp->entity = (Entity_t *) sp; sp->condition = scp; } lock_release (dp->lock); return ((DDS_StatusCondition) scp); }
DDS_ReturnCode_t DDS_Subscriber_set_listener (DDS_Subscriber sp, DDS_SubscriberListener *listener, DDS_StatusMask mask) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_printd (DCPS_ID, DCPS_S_S_LIS, &sp, sizeof (sp)); ctrc_contd (&listener, sizeof (listener)); ctrc_contd (&mask, sizeof (mask)); ctrc_endd (); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); dcps_update_listener ((Entity_t *) sp, &dp->lock, &sp->mask, &sp->listener, mask, listener); lock_release (dp->lock); return (DDS_RETCODE_OK); }
DDS_ReturnCode_t DDS_Subscriber_set_qos (DDS_Subscriber sp, DDS_SubscriberQos *qos) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_printd (DCPS_ID, DCPS_S_S_QOS, &sp, sizeof (sp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); if (qos == DDS_PUBLISHER_QOS_DEFAULT) qos = &sp->domain->def_subscriber_qos; else if (!qos_valid_subscriber_qos (qos)) { ret = DDS_RETCODE_BAD_PARAMETER; goto done; } ret = qos_subscriber_update (&sp->qos, qos); if (ret == DDS_RETCODE_OK) sl_walk (&sp->domain->participant.p_endpoints, update_reader_qos, sp); done: lock_release (dp->lock); return (ret); }
DDS_InstanceHandle_t DDS_Subscriber_get_instance_handle (DDS_Subscriber sp) { ctrc_printd (DCPS_ID, DCPS_S_G_HANDLE, &sp, sizeof (sp)); if (!subscriber_ptr (sp, NULL)) return (0); return (sp->entity.handle); }
DDS_ReturnCode_t DDS_DomainParticipant_delete_subscriber (DDS_DomainParticipant dp, DDS_Subscriber sp) { Condition_t *cp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_DP_D_SUB, &dp, sizeof (dp)); ctrc_contd (&sp, sizeof (sp)); ctrc_endd (); prof_start (dcps_delete_sub); if (!domain_ptr (dp, 1, &ret)) return (ret); if (!subscriber_ptr (sp, &ret)) goto done; if (sp->domain != dp) { ret = DDS_RETCODE_BAD_PARAMETER; goto done; } if (sp->nreaders) { log_printf (DCPS_ID, 0, "delete_subscriber(): still readers connected!\r\n"); ret = DDS_RETCODE_PRECONDITION_NOT_MET; goto done; } if (!dds_purge_notifications ((Entity_t *) sp, DDS_ALL_STATUS, 1)) { ret = DDS_RETCODE_PRECONDITION_NOT_MET; goto done; } sp->entity.flags &= ~EF_ENABLED; qos_subscriber_free (&sp->qos); /* Delete StatusCondition if it exists. */ if (sp->condition) { cp = (Condition_t *) sp->condition; if (cp->deferred) dds_defer_waitset_undo (sp, sp->condition); dcps_delete_status_condition (sp->condition); sp->condition = NULL; } subscriber_delete (sp); done: lock_release (dp->lock); prof_stop (dcps_delete_sub, 1); return (ret); }
DDS_DomainParticipant DDS_Subscriber_get_participant (DDS_Subscriber sp) { Domain_t *dp; DDS_DomainParticipant part; ctrc_printd (DCPS_ID, DCPS_S_G_PART, &sp, sizeof (sp)); if (!subscriber_ptr (sp, NULL)) return (NULL); dp = domain_ptr (sp->domain, 1, NULL); if (!dp) return (NULL); part = sp->domain; lock_release (dp->lock); return (part); }
DDS_StatusMask DDS_Subscriber_get_status_changes (DDS_Subscriber sp) { Domain_t *dp; DDS_StatusMask m; ctrc_printd (DCPS_ID, DCPS_S_G_STAT, &sp, sizeof (sp)); if (!subscriber_ptr (sp, NULL)) return (0); dp = domain_ptr (sp->domain, 1, NULL); if (!dp) return (0); m = sp->status; lock_release (dp->lock); return (m); }
DDS_SubscriberListener *DDS_Subscriber_get_listener (DDS_Subscriber sp) { Domain_t *dp; DDS_SubscriberListener *lp; ctrc_printd (DCPS_ID, DCPS_S_G_LIS, &sp, sizeof (sp)); if (!subscriber_ptr (sp, NULL)) return (NULL); dp = domain_ptr (sp->domain, 1, NULL); if (!dp) return (NULL); lp = &sp->listener; lock_release (dp->lock); return (lp); }
DDS_ReturnCode_t DDS_Subscriber_notify_datareaders (DDS_Subscriber sp) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_printd (DCPS_ID, DCPS_S_NOTIF_DR, &sp, sizeof (sp)); if (!subscriber_ptr (sp, &ret)) return (ret); dp = sp->domain; if (!dp || lock_take (dp->lock)) return (DDS_RETCODE_ALREADY_DELETED); sl_walk (&dp->participant.p_endpoints, subscriber_notify_reader, sp); lock_release (dp->lock); return (ret); }
DDS_ReturnCode_t DDS_Subscriber_get_datareaders (DDS_Subscriber sp, DDS_DataReaderSeq *readers, DDS_SampleStateMask sample_states, DDS_ViewStateMask view_states, DDS_InstanceStateMask instance_states) { Domain_t *dp; SubGReaders_t srd; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_S_G_DR_S, &sp, sizeof (sp)); ctrc_contd (&readers, sizeof (readers)); ctrc_contd (&sample_states, sizeof (sample_states)); ctrc_contd (&view_states, sizeof (view_states)); ctrc_contd (&instance_states, sizeof (instance_states)); ctrc_endd (); if (!readers) return (DDS_RETCODE_BAD_PARAMETER); srd.sp = subscriber_ptr (sp, &ret); if (!srd.sp) return (ret); DDS_SEQ_INIT (*readers); srd.rseq = readers; srd.skip = dcps_skip_mask (sample_states, view_states, instance_states); srd.ret = DDS_RETCODE_OK; dp = srd.sp->domain; if (!dp || lock_take (dp->lock)) return (DDS_RETCODE_ALREADY_DELETED); sl_walk (&dp->participant.p_endpoints, subscriber_get_reader, &srd); lock_release (dp->lock); return (srd.ret); }
DDS_ReturnCode_t DDS_Subscriber_copy_from_topic_qos (DDS_Subscriber sp, DDS_DataReaderQos *rqos, DDS_TopicQos *tqos) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_S_DR_F_TQOS, &sp, sizeof (sp)); ctrc_contd (&rqos, sizeof (rqos)); ctrc_contd (&tqos, sizeof (tqos)); ctrc_endd (); if (!rqos) return (DDS_RETCODE_BAD_PARAMETER); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); if (!tqos) tqos = &dp->def_topic_qos; rqos->durability = tqos->durability; rqos->deadline = tqos->deadline; rqos->latency_budget = tqos->latency_budget; rqos->liveliness = tqos->liveliness; rqos->reliability = tqos->reliability; rqos->destination_order = tqos->destination_order; rqos->history = tqos->history; rqos->resource_limits = tqos->resource_limits; rqos->ownership = tqos->ownership; lock_release (dp->lock); return (DDS_RETCODE_OK); }
DDS_ReturnCode_t DDS_Subscriber_get_qos (DDS_Subscriber sp, DDS_SubscriberQos *qos) { Domain_t *dp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_S_G_QOS, &sp, sizeof (sp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!qos) return (DDS_RETCODE_BAD_PARAMETER); if (!subscriber_ptr (sp, &ret)) return (ret); dp = domain_ptr (sp->domain, 1, &ret); if (!dp) return (ret); qos_subscriber_get (&sp->qos, qos); lock_release (dp->lock); return (DDS_RETCODE_OK); }
DDS_DataReader DDS_Subscriber_create_datareader (DDS_Subscriber sp, DDS_TopicDescription topic, const DDS_DataReaderQos *qos, const DDS_DataReaderListener *listener, DDS_StatusMask mask) { Domain_t *dp; Topic_t *tp; Participant_t *pp; Reader_t *rp; Cache_t cp; EntityId_t eid; #ifdef DDS_NATIVE_SECURITY unsigned secure; DDS_ReturnCode_t ret; #endif const TypeSupport_t *ts; int error; ctrc_begind (DCPS_ID, DCPS_S_C_DR, &sp, sizeof (sp)); ctrc_contd (&topic, sizeof (topic)); ctrc_contd (&qos, sizeof (qos)); ctrc_contd (&listener, sizeof (listener)); ctrc_contd (&mask, sizeof (mask)); ctrc_endd (); prof_start (dcps_create_reader); if (!subscriber_ptr (sp, NULL)) return (NULL); dp = sp->domain; if (!dp || lock_take (dp->lock)) return (NULL); if (sp->domain != dp) goto inv_topic; /*DDS_RETCODE_BAD_PARAMETER*/ tp = topic_ptr (topic, 1, NULL); if (!tp) goto inv_topic; rp = NULL; /* Don't check whether reader is already created! Multiple readers and or writers on the same topic are definitely allowed! */ if (qos == DDS_DATAREADER_QOS_DEFAULT) qos = &sp->def_reader_qos; else if (qos != DDS_DATAREADER_QOS_USE_TOPIC_QOS && !qos_valid_reader_qos (qos)) goto done; #ifdef DDS_SECURITY /* Check if security policy allows this datareader. */ #ifdef DDS_NATIVE_SECURITY if (sec_check_create_reader (dp->participant.p_permissions, str_ptr (tp->name), NULL, qos, sp->qos.partition, NULL, &secure)) { #else if (check_create_reader (dp->participant.p_permissions, tp, qos, sp->qos.partition)) { #endif log_printf (DCPS_ID, 0, "create_datareader: reader create not allowed!\r\n"); goto done; } #endif /* Create an Entity Identifier. */ ts = tp->type->type_support; if ((sp->entity.flags & EF_BUILTIN) != 0) { eid.id [0] = eid.id [1] = 0; eid.id [2] = 0x10 + tp->type->index; eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_BUILTIN | ENTITY_KIND_READER_KEY; } else { ++dcps_entity_count; eid.id [0] = (dcps_entity_count >> 16) & 0xff; eid.id [1] = (dcps_entity_count >> 8) & 0xff; eid.id [2] = dcps_entity_count & 0xff; if (ts->ts_keys) eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER_KEY; else eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER; } pp = &dp->participant; rp = (Reader_t *) endpoint_create (pp, sp, &eid, NULL); if (!rp) { warn_printf ("create_datareader: out of memory for DataReader structure.\r\n"); goto done; } #ifdef RW_LOCKS lock_take (rp->r_lock); #endif if ((sp->entity.flags & EF_BUILTIN) != 0) rp->r_flags |= EF_BUILTIN; if (qos == DDS_DATAREADER_QOS_USE_TOPIC_QOS) { rp->r_qos = tp->qos; tp->qos->users++; qos_init_time_based_filter (&rp->r_time_based_filter); qos_init_reader_data_lifecycle (&rp->r_data_lifecycle); } else { rp->r_qos = qos_reader_new (qos); rp->r_time_based_filter = qos->time_based_filter; rp->r_data_lifecycle = qos->reader_data_lifecycle; } if (!rp->r_qos) goto free_pool; rp->r_mask = mask; if (listener) rp->r_listener = *listener; else memset (&rp->r_listener, 0, sizeof (rp->r_listener)); memset (&rp->r_rdm_status, 0, sizeof (rp->r_rdm_status)); memset (&rp->r_riq_status, 0, sizeof (rp->r_riq_status)); memset (&rp->r_sl_status, 0, sizeof (rp->r_sl_status)); memset (&rp->r_sr_status, 0, sizeof (rp->r_sr_status)); memset (&rp->r_lc_status, 0, sizeof (rp->r_lc_status)); memset (&rp->r_sm_status, 0, sizeof (rp->r_sm_status)); rp->r_changes.buffer = NULL; rp->r_changes.length = rp->r_changes.maximum = 0; rp->r_prev_info = NULL; rp->r_prev_data = NULL; rp->r_n_prev = 0; rp->r_topic = tp; rp->r_next = tp->readers; tp->readers = &rp->r_ep; #ifdef DDS_NATIVE_SECURITY /* Set security attributes. */ rp->r_access_prot = 0; rp->r_disc_prot = 0; rp->r_submsg_prot = 0; rp->r_payload_prot = 0; rp->r_crypto_type = 0; rp->r_crypto = 0; if (secure && (dp->participant.p_sec_caps & (SECC_DDS_SEC | (SECC_DDS_SEC << SECC_LOCAL))) != 0) { log_printf (DCPS_ID, 0, "DDS: Reader security attributes: 0x%x\r\n", secure); rp->r_access_prot = (secure & DDS_SECA_ACCESS_PROTECTED) != 0; rp->r_disc_prot = (secure & DDS_SECA_DISC_PROTECTED) != 0; rp->r_submsg_prot = (secure & DDS_SECA_SUBMSG_PROTECTED) != 0; rp->r_payload_prot = (secure & DDS_SECA_PAYLOAD_PROTECTED) != 0; if (rp->r_submsg_prot || rp->r_payload_prot) { rp->r_crypto_type = secure >> DDS_SECA_ENCRYPTION_SHIFT; rp->r_crypto = sec_register_local_datareader (dp->participant.p_crypto, rp, &ret); } }