mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-27 23:55:57 -05:00
Add evrtsp - RTSP implementation on top of libevent, derived from evhttp
This commit is contained in:
parent
8427707afc
commit
992eb9009a
169
src/evrtsp/evrtsp.h
Normal file
169
src/evrtsp/evrtsp.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Julien BLACHE <jb@jblache.org>
|
||||
* Based on evhttp from libevent 1.4.x
|
||||
*
|
||||
* Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVRTSP_H_
|
||||
#define _EVRTSP_H_
|
||||
|
||||
#include <event.h>
|
||||
#include <evhttp.h> /* FIXME: forked-daapd's one */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
/* Response codes */
|
||||
#define RTSP_OK 200
|
||||
#define RTSP_UNAUTHORIZED 401
|
||||
|
||||
struct evrtsp_connection;
|
||||
|
||||
/*
|
||||
* Interfaces for making requests
|
||||
*/
|
||||
enum evrtsp_cmd_type {
|
||||
EVRTSP_REQ_ANNOUNCE,
|
||||
EVRTSP_REQ_OPTIONS,
|
||||
EVRTSP_REQ_SETUP,
|
||||
EVRTSP_REQ_RECORD,
|
||||
EVRTSP_REQ_PAUSE,
|
||||
EVRTSP_REQ_GET_PARAMETER,
|
||||
EVRTSP_REQ_SET_PARAMETER,
|
||||
EVRTSP_REQ_FLUSH,
|
||||
EVRTSP_REQ_TEARDOWN,
|
||||
};
|
||||
|
||||
enum evrtsp_request_kind { EVRTSP_REQUEST, EVRTSP_RESPONSE };
|
||||
|
||||
struct evrtsp_request {
|
||||
#if defined(TAILQ_ENTRY)
|
||||
TAILQ_ENTRY(evrtsp_request) next;
|
||||
#else
|
||||
struct {
|
||||
struct evrtsp_request *tqe_next;
|
||||
struct evrtsp_request **tqe_prev;
|
||||
} next;
|
||||
#endif
|
||||
|
||||
/* the connection object that this request belongs to */
|
||||
struct evrtsp_connection *evcon;
|
||||
int flags;
|
||||
#define EVRTSP_REQ_OWN_CONNECTION 0x0001
|
||||
|
||||
struct evkeyvalq *input_headers;
|
||||
struct evkeyvalq *output_headers;
|
||||
|
||||
enum evrtsp_request_kind kind;
|
||||
enum evrtsp_cmd_type type;
|
||||
|
||||
char *uri; /* uri after RTSP request was parsed */
|
||||
|
||||
char major; /* RTSP Major number */
|
||||
char minor; /* RTSP Minor number */
|
||||
|
||||
int response_code; /* RTSP Response code */
|
||||
char *response_code_line; /* Readable response */
|
||||
|
||||
struct evbuffer *input_buffer; /* read data */
|
||||
ev_int64_t ntoread;
|
||||
|
||||
struct evbuffer *output_buffer; /* outgoing post or data */
|
||||
|
||||
/* Callback */
|
||||
void (*cb)(struct evrtsp_request *, void *);
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new request object that needs to be filled in with the request
|
||||
* parameters. The callback is executed when the request completed or an
|
||||
* error occurred.
|
||||
*/
|
||||
struct evrtsp_request *evrtsp_request_new(
|
||||
void (*cb)(struct evrtsp_request *, void *), void *arg);
|
||||
|
||||
/** Frees the request object and removes associated events. */
|
||||
void evrtsp_request_free(struct evrtsp_request *req);
|
||||
|
||||
/**
|
||||
* A connection object that can be used to for making RTSP requests. The
|
||||
* connection object tries to establish the connection when it is given an
|
||||
* rtsp request object.
|
||||
*/
|
||||
struct evrtsp_connection *evrtsp_connection_new(
|
||||
const char *address, unsigned short port);
|
||||
|
||||
/** Frees an rtsp connection */
|
||||
void evrtsp_connection_free(struct evrtsp_connection *evcon);
|
||||
|
||||
/** Set a callback for connection close. */
|
||||
void evrtsp_connection_set_closecb(struct evrtsp_connection *evcon,
|
||||
void (*)(struct evrtsp_connection *, void *), void *);
|
||||
|
||||
/**
|
||||
* Associates an event base with the connection - can only be called
|
||||
* on a freshly created connection object that has not been used yet.
|
||||
*/
|
||||
void evrtsp_connection_set_base(struct evrtsp_connection *evcon,
|
||||
struct event_base *base);
|
||||
|
||||
/** Get the remote address and port associated with this connection. */
|
||||
void evrtsp_connection_get_peer(struct evrtsp_connection *evcon,
|
||||
char **address, u_short *port);
|
||||
|
||||
/** Get the local address and port associated with this connection. */
|
||||
void
|
||||
evrtsp_connection_get_local_address(struct evrtsp_connection *evcon,
|
||||
char **address, u_short *port);
|
||||
|
||||
/** The connection gets ownership of the request */
|
||||
int evrtsp_make_request(struct evrtsp_connection *evcon,
|
||||
struct evrtsp_request *req,
|
||||
enum evrtsp_cmd_type type, const char *uri);
|
||||
|
||||
const char *evrtsp_request_uri(struct evrtsp_request *req);
|
||||
|
||||
/* Interfaces for dealing with headers */
|
||||
|
||||
const char *evrtsp_find_header(const struct evkeyvalq *, const char *);
|
||||
int evrtsp_remove_header(struct evkeyvalq *, const char *);
|
||||
int evrtsp_add_header(struct evkeyvalq *, const char *, const char *);
|
||||
void evrtsp_clear_headers(struct evkeyvalq *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_EVRTSP_H_ */
|
51
src/evrtsp/log.h
Normal file
51
src/evrtsp/log.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
|
||||
#else
|
||||
#define EV_CHECK_FMT(a,b)
|
||||
#endif
|
||||
|
||||
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
||||
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
||||
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||
void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||
void _event_debugx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||
|
||||
#ifdef USE_DEBUG
|
||||
#define event_debug(x) _event_debugx x
|
||||
#else
|
||||
#define event_debug(x) do {;} while (0)
|
||||
#endif
|
||||
|
||||
#undef EV_CHECK_FMT
|
||||
|
||||
#endif
|
108
src/evrtsp/rtsp-internal.h
Normal file
108
src/evrtsp/rtsp-internal.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Julien BLACHE <jb@jblache.org>
|
||||
* Based on evhttp from libevent 1.4.x
|
||||
*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This header file contains definitions for dealing with RTSP requests
|
||||
* that are internal to libevent. As user of the library, you should not
|
||||
* need to know about these.
|
||||
*/
|
||||
|
||||
#ifndef _RTSP_H_
|
||||
#define _RTSP_H_
|
||||
|
||||
#define RTSP_CONNECT_TIMEOUT 45
|
||||
#define RTSP_WRITE_TIMEOUT 50
|
||||
#define RTSP_READ_TIMEOUT 50
|
||||
|
||||
#define RTSP_PREFIX "rtsp://"
|
||||
|
||||
enum message_read_status {
|
||||
ALL_DATA_READ = 1,
|
||||
MORE_DATA_EXPECTED = 0,
|
||||
DATA_CORRUPTED = -1,
|
||||
REQUEST_CANCELED = -2
|
||||
};
|
||||
|
||||
enum evrtsp_connection_error {
|
||||
EVCON_RTSP_TIMEOUT,
|
||||
EVCON_RTSP_EOF,
|
||||
EVCON_RTSP_INVALID_HEADER
|
||||
};
|
||||
|
||||
struct evbuffer;
|
||||
struct addrinfo;
|
||||
struct evrtsp_request;
|
||||
|
||||
/* A stupid connection object - maybe make this a bufferevent later */
|
||||
|
||||
enum evrtsp_connection_state {
|
||||
EVCON_DISCONNECTED, /**< not currently connected not trying either*/
|
||||
EVCON_CONNECTING, /**< tries to currently connect */
|
||||
EVCON_IDLE, /**< connection is established */
|
||||
EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or
|
||||
**< Status-Line (outgoing conn) */
|
||||
EVCON_READING_HEADERS, /**< reading request/response headers */
|
||||
EVCON_READING_BODY, /**< reading request/response body */
|
||||
EVCON_READING_TRAILER, /**< reading request/response chunked trailer */
|
||||
EVCON_WRITING /**< writing request/response headers/body */
|
||||
};
|
||||
|
||||
struct event_base;
|
||||
|
||||
struct evrtsp_connection {
|
||||
int fd;
|
||||
struct event ev;
|
||||
struct event close_ev;
|
||||
struct evbuffer *input_buffer;
|
||||
struct evbuffer *output_buffer;
|
||||
|
||||
char *bind_address; /* address to use for binding the src */
|
||||
u_short bind_port; /* local port for binding the src */
|
||||
|
||||
char *address; /* address to connect to */
|
||||
u_short port;
|
||||
|
||||
int flags;
|
||||
#define EVRTSP_CON_CLOSEDETECT 0x0004 /* detecting if persistent close */
|
||||
|
||||
int timeout; /* timeout in seconds for events */
|
||||
|
||||
enum evrtsp_connection_state state;
|
||||
int cseq;
|
||||
|
||||
TAILQ_HEAD(evcon_requestq, evrtsp_request) requests;
|
||||
|
||||
void (*cb)(struct evrtsp_connection *, void *);
|
||||
void *cb_arg;
|
||||
|
||||
void (*closecb)(struct evrtsp_connection *, void *);
|
||||
void *closecb_arg;
|
||||
|
||||
struct event_base *base;
|
||||
};
|
||||
|
||||
/* resets the connection; can be reused for more requests */
|
||||
void evrtsp_connection_reset(struct evrtsp_connection *);
|
||||
|
||||
/* connects if necessary */
|
||||
int evrtsp_connection_connect(struct evrtsp_connection *);
|
||||
|
||||
/* notifies the current request that it failed; resets connection */
|
||||
void evrtsp_connection_fail(struct evrtsp_connection *,
|
||||
enum evrtsp_connection_error error);
|
||||
|
||||
int evrtsp_hostportfile(char *, char **, u_short *, char **);
|
||||
|
||||
int evrtsp_parse_firstline(struct evrtsp_request *, struct evbuffer*);
|
||||
int evrtsp_parse_headers(struct evrtsp_request *, struct evbuffer*);
|
||||
|
||||
void evrtsp_start_read(struct evrtsp_connection *);
|
||||
void evrtsp_make_header(struct evrtsp_connection *, struct evrtsp_request *);
|
||||
|
||||
void evrtsp_write_buffer(struct evrtsp_connection *,
|
||||
void (*)(struct evrtsp_connection *, void *), void *);
|
||||
|
||||
#endif /* _RTSP_H */
|
1784
src/evrtsp/rtsp.c
Normal file
1784
src/evrtsp/rtsp.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user