diff --git a/src/modules/module-rtp-sap.c b/src/modules/module-rtp-sap.c index 6634dab6a..4dd824211 100644 --- a/src/modules/module-rtp-sap.c +++ b/src/modules/module-rtp-sap.c @@ -662,15 +662,24 @@ static bool update_ts_refclk(struct impl *impl) return gmid_changed; } -static int make_sdp(struct impl *impl, struct session *sess, char *buffer, size_t buffer_size) +static uint16_t generate_hash(uint16_t prev) +{ + uint16_t hash = pw_rand32(); + if (hash == prev) hash++; + if (hash == 0) hash++; + return hash; +} + +static int make_sdp(struct impl *impl, struct session *sess, char *buffer, size_t buffer_size, bool new) { char src_addr[64], dst_addr[64], dst_ttl[8], ptime[32]; struct sdp_info *sdp = &sess->info; bool src_ip4, dst_ip4; bool multicast; - const char *user_name; + const char *user_name, *str; struct spa_strbuf buf; int res; + struct pw_properties *props = sess->props; if ((res = pw_net_get_ip(&impl->src_addr, src_addr, sizeof(src_addr), &src_ip4, NULL)) < 0) return res; @@ -678,6 +687,30 @@ static int make_sdp(struct impl *impl, struct session *sess, char *buffer, size_ if ((res = pw_net_get_ip(&sdp->dst_addr, dst_addr, sizeof(dst_addr), &dst_ip4, NULL)) < 0) return res; + if (new) { + /* update the version and hash */ + sdp->hash = generate_hash(sdp->hash); + if ((str = pw_properties_get(props, "sess.id")) != NULL) { + if (!spa_atou32(str, &sdp->session_id, 10)) { + pw_log_error("Invalid session id: %s (must be a uint32)", str); + return -EINVAL; + } + sdp->t_ntp = pw_properties_get_uint32(props, "rtp.ntp", + (uint32_t) time(NULL) + 2208988800U + impl->n_sessions); + } else { + sdp->session_id = (uint32_t) time(NULL) + 2208988800U + impl->n_sessions; + sdp->t_ntp = pw_properties_get_uint32(props, "rtp.ntp", sdp->session_id); + } + if ((str = pw_properties_get(props, "sess.version")) != NULL) { + if (!spa_atou32(str, &sdp->session_version, 10)) { + pw_log_error("Invalid session version: %s (must be a uint32)", str); + return -EINVAL; + } + } else { + sdp->session_version = sdp->t_ntp; + } + } + if ((user_name = pw_get_user_name()) == NULL) user_name = "-"; @@ -839,7 +872,7 @@ static int send_sap(struct impl *impl, struct session *sess, bool bye) * socket needs to be open for us to get the interface address (which * happens above. So let's create the SDP now, if needed. */ if (!sess->has_sdp) { - res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp)); + res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp), true); if (res != 0) { pw_log_error("Failed to create SDP: %s", spa_strerror(res)); return res; @@ -887,20 +920,13 @@ static int send_sap(struct impl *impl, struct session *sess, bool bye) return res; } -static uint16_t generate_hash(uint16_t prev) -{ - uint16_t hash = pw_rand32(); - if (hash == prev) hash++; - if (hash == 0) hash++; - return hash; -} - static void on_timer_event(void *data, uint64_t expirations) { struct impl *impl = data; struct session *sess, *tmp; uint64_t timestamp, interval; bool clk_changed; + int res; timestamp = get_time_nsec(impl); interval = impl->cleanup_interval * SPA_NSEC_PER_SEC; @@ -911,12 +937,12 @@ static void on_timer_event(void *data, uint64_t expirations) if (clk_changed) { // The clock has changed: Send bye and create new SDP. send_sap(impl, sess, 1); - sess->info.hash = generate_hash(sess->info.hash); - int res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp)); - if (res != 0) { + res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp), true); + if (res != 0) pw_log_error("Failed to create SDP: %s", spa_strerror(res)); - } + else + sess->has_sdp = true; } send_sap(impl, sess, 0); } else { @@ -1045,44 +1071,19 @@ static struct session *session_new_announce(struct impl *impl, struct node *node /* see if we can make an SDP, will fail for the first session because we * haven't got the SAP socket open yet */ - res = make_sdp(impl, sess, buffer, sizeof(buffer)); + res = make_sdp(impl, sess, buffer, sizeof(buffer), false); /* we had no sdp or something changed */ if (!sess->has_sdp || ((res == 0) && strcmp(buffer, sess->sdp) != 0)) { /* send bye on the old session */ send_sap(impl, sess, 1); - /* update the version and hash */ - sdp->hash = generate_hash(sdp->hash); - if ((str = pw_properties_get(props, "sess.id")) != NULL) { - if (!spa_atou32(str, &sdp->session_id, 10)) { - pw_log_error("Invalid session id: %s (must be a uint32)", str); - goto error_free; - } - sdp->t_ntp = pw_properties_get_uint32(props, "rtp.ntp", - (uint32_t) time(NULL) + 2208988800U + impl->n_sessions); - } else { - sdp->session_id = (uint32_t) time(NULL) + 2208988800U + impl->n_sessions; - sdp->t_ntp = pw_properties_get_uint32(props, "rtp.ntp", sdp->session_id); - } - if ((str = pw_properties_get(props, "sess.version")) != NULL) { - if (!spa_atou32(str, &sdp->session_version, 10)) { - pw_log_error("Invalid session version: %s (must be a uint32)", str); - goto error_free; - } - } else { - sdp->session_version = sdp->t_ntp; - } - - if (res == 0) { - /* make an updated SDP for sending, this should not actually fail */ - res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp)); - - if (res == 0) - sess->has_sdp = true; - else - pw_log_error("Failed to create SDP: %s", spa_strerror(res)); - } + /* make an updated SDP for sending, this should not actually fail */ + res = make_sdp(impl, sess, sess->sdp, sizeof(sess->sdp), true); + if (res != 0) + pw_log_error("Failed to create SDP: %s", spa_strerror(res)); + else + sess->has_sdp = true; } send_sap(impl, sess, 0);