int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime) { pa_headerlist* headers; int rv; char *info; pa_assert(c); if (!c->session) { /* No session in progress */ return -1; } /* Todo: Generate these values randomly as per spec */ *seq = *rtptime = 0; headers = pa_headerlist_new(); pa_headerlist_puts(headers, "Range", "npt=0-"); info = pa_sprintf_malloc("seq=%u;rtptime=%u", *seq, *rtptime); pa_headerlist_puts(headers, "RTP-Info", info); pa_xfree(info); c->state = STATE_RECORD; rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers); pa_headerlist_free(headers); return rv; }
int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime) { pa_headerlist *headers; char *info; int rv; pa_assert(c); if (!c->session) { /* No session in progress */ return -1; } pa_random(seq, sizeof(*seq)); pa_random(rtptime, sizeof(*rtptime)); headers = pa_headerlist_new(); pa_headerlist_puts(headers, "Range", "npt=0-"); info = pa_sprintf_malloc("seq=%u;rtptime=%u", *seq, *rtptime); pa_headerlist_puts(headers, "RTP-Info", info); pa_xfree(info); c->state = STATE_RECORD; rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers); pa_headerlist_free(headers); return rv; }
void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value) { pa_assert(c); pa_assert(key); pa_assert(value); pa_headerlist_puts(c->headers, key, value); }
int pa_rtsp_setup(pa_rtsp_client *c, const char *transport) { pa_headerlist *headers; int rv; pa_assert(c); headers = pa_headerlist_new(); if (!transport) pa_headerlist_puts(headers, "Transport", "RTP/AVP/TCP;unicast;interleaved=0-1;mode=record"); else pa_headerlist_puts(headers, "Transport", transport); c->state = STATE_SETUP; rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers); pa_headerlist_free(headers); return rv; }
int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) { pa_headerlist* headers; int rv; char *info; pa_assert(c); headers = pa_headerlist_new(); info = pa_sprintf_malloc("seq=%u;rtptime=%u", seq, rtptime); pa_headerlist_puts(headers, "RTP-Info", info); pa_xfree(info); c->state = STATE_FLUSH; rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers); pa_headerlist_free(headers); return rv; }
static void line_callback(pa_ioline *line, const char *s, void *userdata) { char *delimpos; char *s2, *s2p; pa_rtsp_client *c = userdata; pa_assert(line); pa_assert(c); pa_assert(c->callback); if (!s) { /* Keep the ioline/iochannel open as they will be freed automatically */ c->ioline = NULL; c->callback(c, STATE_DISCONNECTED, NULL, c->userdata); return; } s2 = pa_xstrdup(s); /* Trim trailing carriage returns */ s2p = s2 + strlen(s2) - 1; while (s2p >= s2 && '\r' == *s2p) { *s2p = '\0'; s2p -= 1; } if (c->waiting && 0 == strcmp("RTSP/1.0 200 OK", s2)) { c->waiting = 0; if (c->response_headers) pa_headerlist_free(c->response_headers); c->response_headers = pa_headerlist_new(); goto exit; } if (c->waiting) { pa_log_warn("Unexpected response: %s", s2); goto exit;; } if (!strlen(s2)) { /* End of headers */ /* We will have a header left from our looping iteration, so add it in :) */ if (c->last_header) { char *tmp = pa_strbuf_tostring_free(c->header_buffer); /* This is not a continuation header so let's dump it into our proplist */ pa_headerlist_puts(c->response_headers, c->last_header, tmp); pa_xfree(tmp); pa_xfree(c->last_header); c->last_header = NULL; c->header_buffer = NULL; } pa_log_debug("Full response received. Dispatching"); headers_read(c); c->waiting = 1; goto exit; } /* Read and parse a header (we know it's not empty) */ /* TODO: Move header reading into the headerlist. */ /* If the first character is a space, it's a continuation header */ if (c->last_header && ' ' == s2[0]) { pa_assert(c->header_buffer); /* Add this line to the buffer (sans the space. */ pa_strbuf_puts(c->header_buffer, &(s2[1])); goto exit; } if (c->last_header) { char *tmp = pa_strbuf_tostring_free(c->header_buffer); /* This is not a continuation header so let's dump the full header/value into our proplist */ pa_headerlist_puts(c->response_headers, c->last_header, tmp); pa_xfree(tmp); pa_xfree(c->last_header); c->last_header = NULL; c->header_buffer = NULL; } delimpos = strstr(s2, ":"); if (!delimpos) { pa_log_warn("Unexpected response when expecting header: %s", s); goto exit; } pa_assert(!c->header_buffer); pa_assert(!c->last_header); c->header_buffer = pa_strbuf_new(); if (strlen(delimpos) > 1) { /* Cut our line off so we can copy the header name out */ *delimpos++ = '\0'; /* Trim the front of any spaces */ while (' ' == *delimpos) ++delimpos; pa_strbuf_puts(c->header_buffer, delimpos); } else { /* Cut our line off so we can copy the header name out */ *delimpos = '\0'; } /* Save the header name */ c->last_header = pa_xstrdup(s2); exit: pa_xfree(s2); }