int rtsp_setup( http_client_t *hc, const char *path, const char *query, const char *multicast_addr, int rtp_port, int rtcp_port ) { http_arg_list_t h; char transport[256]; if (rtcp_port < 0) { snprintf(transport, sizeof(transport), "RTP/AVP/TCP;interleaved=%d-%d", rtp_port, rtp_port + 1); } else if (multicast_addr) { snprintf(transport, sizeof(transport), "RTP/AVP;multicast;destination=%s;ttl=1;client_port=%i-%i", multicast_addr, rtp_port, rtcp_port); } else { snprintf(transport, sizeof(transport), "RTP/AVP;unicast;client_port=%i-%i", rtp_port, rtcp_port); } http_arg_init(&h); http_arg_set(&h, "Transport", transport); return rtsp_send(hc, RTSP_CMD_SETUP, path, query, &h); }
/* * Alive timeout */ static void iptv_rtsp_alive_cb ( void *aux ) { iptv_mux_t *im = aux; rtsp_priv_t *rp = im->im_data; rtsp_send(rp->hc, RTSP_CMD_OPTIONS, rp->path, rp->query, NULL); gtimer_arm(&rp->alive_timer, iptv_rtsp_alive_cb, im, MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1)); }
/* * Alive timeout */ static void iptv_rtsp_alive_cb ( void *aux ) { iptv_mux_t *im = aux; rtsp_priv_t *rp = im->im_data; if(rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_GET_PARAMETER) rtsp_get_parameter(rp->hc, "position"); else if(rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_OPTIONS) rtsp_send(rp->hc, RTSP_CMD_OPTIONS, rp->path, rp->query, NULL); else return; mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, sec2mono(MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1))); }
static void sink_handle_get_parameter(struct ctl_sink *s, struct rtsp_message *m) { _rtsp_message_unref_ struct rtsp_message *rep = NULL; int r; r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); if (r < 0) return cli_vERR(r); /* wfd_content_protection */ if (rtsp_message_read(m, "{<>}", "wfd_content_protection") >= 0) { r = rtsp_message_append(rep, "{&}", "wfd_content_protection: none"); if (r < 0) return cli_vERR(r); } /* wfd_video_formats */ if (rtsp_message_read(m, "{<>}", "wfd_video_formats") >= 0) { char wfd_video_formats[128]; sprintf(wfd_video_formats, "wfd_video_formats: 00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); r = rtsp_message_append(rep, "{&}", wfd_video_formats); if (r < 0) return cli_vERR(r); } /* wfd_audio_codecs */ if (rtsp_message_read(m, "{<>}", "wfd_audio_codecs") >= 0) { r = rtsp_message_append(rep, "{&}", "wfd_audio_codecs: AAC 00000007 00"); if (r < 0) return cli_vERR(r); } /* wfd_client_rtp_ports */ if (rtsp_message_read(m, "{<>}", "wfd_client_rtp_ports") >= 0) { r = rtsp_message_append(rep, "{&}", "wfd_client_rtp_ports: RTP/AVP/UDP;unicast 1991 0 mode=play"); if (r < 0) return cli_vERR(r); } rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); r = rtsp_send(s->rtsp, rep); if (r < 0) return cli_vERR(r); }
static void sink_handle_options(struct ctl_sink *s, struct rtsp_message *m) { _rtsp_message_unref_ struct rtsp_message *rep = NULL; int r; r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); if (r < 0) return cli_vERR(r); r = rtsp_message_append(rep, "<s>", "Public", "org.wfa.wfd1.0, GET_PARAMETER, SET_PARAMETER"); if (r < 0) return cli_vERR(r); rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); r = rtsp_send(s->rtsp, rep); if (r < 0) return cli_vERR(r); rtsp_message_unref(rep); rep = NULL; r = rtsp_message_new_request(s->rtsp, &rep, "OPTIONS", "*"); if (r < 0) return cli_vERR(r); r = rtsp_message_append(rep, "<s>", "Require", "org.wfa.wfd1.0"); if (r < 0) return cli_vERR(r); rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); r = rtsp_call_async(s->rtsp, rep, sink_req_fn, NULL, 0, NULL); if (r < 0) return cli_vERR(r); }
static void sink_handle_set_parameter(struct ctl_sink *s, struct rtsp_message *m) { _rtsp_message_unref_ struct rtsp_message *rep = NULL; const char *trigger; const char *url; char *nu; unsigned int cea_res, vesa_res, hh_res; int r; r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); if (r < 0) return cli_vERR(r); rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); r = rtsp_send(s->rtsp, rep); if (r < 0) return cli_vERR(r); rtsp_message_unref(rep); rep = NULL; /* M4 (or any other) can pass presentation URLs */ r = rtsp_message_read(m, "{<s>}", "wfd_presentation_URL", &url); if (r >= 0) { if (!s->url || strcmp(s->url, url)) { nu = strdup(url); if (!nu) return cli_vENOMEM(); free(s->url); s->url = nu; cli_debug("Got URL: %s\n", s->url); } } /* M4 again */ r = rtsp_message_read(m, "{<****hhh>}", "wfd_video_formats", &cea_res, &vesa_res, &hh_res); if (r == 0) { r = sink_set_format(s, cea_res, vesa_res, hh_res); if (r) return cli_vERR(r); } /* M5 */ r = rtsp_message_read(m, "{<s>}", "wfd_trigger_method", &trigger); if (r < 0) return; if (!strcmp(trigger, "SETUP")) { if (!s->url) { cli_error("No valid wfd_presentation_URL\n"); return; } r = rtsp_message_new_request(s->rtsp, &rep, "SETUP", s->url); if (r < 0) return cli_vERR(r); r = rtsp_message_append(rep, "<s>", "Transport", "RTP/AVP/UDP;unicast;client_port=1991"); if (r < 0) return cli_vERR(r); rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); r = rtsp_call_async(s->rtsp, rep, sink_setup_fn, s, 0, NULL); if (r < 0) return cli_vERR(r); } }