mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-15 04:42:06 +00:00
miracle-wfdctl: clarify teardown procedure of session
This commit is contained in:
parent
b0419509b8
commit
155060919e
8 changed files with 183 additions and 141 deletions
|
@ -103,10 +103,10 @@ get_prop()
|
||||||
|
|
||||||
cleanup()
|
cleanup()
|
||||||
{
|
{
|
||||||
kill 0
|
set +e
|
||||||
set -x
|
while (( 0 != ${#cleanup[@]} )); do
|
||||||
for (( i=${#cleanup[@]}-1; i>=0; --i )); do
|
eval ${cleanup[${#cleanup[@]}-1]}
|
||||||
eval ${cleanup[$i]} || true
|
unset cleanup[${#cleanup[@]}-1]
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,14 @@ cleanup_push()
|
||||||
cleanup+=("$*")
|
cleanup+=("$*")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nm_manage()
|
||||||
|
{
|
||||||
|
set_prop org.freedesktop.NetworkManager \
|
||||||
|
/org/freedesktop/NetworkManager/Devices/"$nm_link_index" \
|
||||||
|
org.freedesktop.NetworkManager.Device \
|
||||||
|
Managed b true
|
||||||
|
}
|
||||||
|
|
||||||
link_unmanage()
|
link_unmanage()
|
||||||
{
|
{
|
||||||
set_prop org.freedesktop.miracle.wifi \
|
set_prop org.freedesktop.miracle.wifi \
|
||||||
|
@ -149,6 +157,7 @@ set_prop org.freedesktop.NetworkManager \
|
||||||
/org/freedesktop/NetworkManager/Devices/"$nm_link_index" \
|
/org/freedesktop/NetworkManager/Devices/"$nm_link_index" \
|
||||||
org.freedesktop.NetworkManager.Device \
|
org.freedesktop.NetworkManager.Device \
|
||||||
Managed b false
|
Managed b false
|
||||||
|
cleanup_push nm_manage
|
||||||
set_prop org.freedesktop.miracle.wifi \
|
set_prop org.freedesktop.miracle.wifi \
|
||||||
/org/freedesktop/miracle/wifi/link/$link_index \
|
/org/freedesktop/miracle/wifi/link/$link_index \
|
||||||
org.freedesktop.miracle.wifi.Link \
|
org.freedesktop.miracle.wifi.Link \
|
||||||
|
@ -179,6 +188,8 @@ get_prop org.freedesktop.miracle.wifi \
|
||||||
org.freedesktop.miracle.wifi.Peer \
|
org.freedesktop.miracle.wifi.Peer \
|
||||||
Interface p2p_iface
|
Interface p2p_iface
|
||||||
tcpdump -nnvvXS -s 0 -i $p2p_iface port 7236 or port 67 or port 68 &
|
tcpdump -nnvvXS -s 0 -i $p2p_iface port 7236 or port 67 or port 68 &
|
||||||
|
cleanup_push "kill $!"
|
||||||
|
|
||||||
while ! killall -0 miracle-wfdctl && [[ -z "$nocheck" ]] &>/dev/null; do
|
while ! killall -0 miracle-wfdctl && [[ -z "$nocheck" ]] &>/dev/null; do
|
||||||
echo please run miracle-wfdctl manually
|
echo please run miracle-wfdctl manually
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|
|
@ -198,6 +198,8 @@ struct wfd_sink
|
||||||
union wfd_sube dev_info;
|
union wfd_sube dev_info;
|
||||||
char *label;
|
char *label;
|
||||||
struct wfd_session *session;
|
struct wfd_session *session;
|
||||||
|
|
||||||
|
sd_event_source *session_cleanup_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
int wfd_sink_new(struct wfd_sink **out,
|
int wfd_sink_new(struct wfd_sink **out,
|
||||||
|
@ -237,6 +239,8 @@ struct ctl_wfd
|
||||||
struct shl_htable sessions;
|
struct shl_htable sessions;
|
||||||
size_t n_sessions;
|
size_t n_sessions;
|
||||||
uint64_t id_pool;
|
uint64_t id_pool;
|
||||||
|
|
||||||
|
sd_event_source *signal_sources[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ctl_wfd * ctl_wfd_get();
|
struct ctl_wfd * ctl_wfd_get();
|
||||||
|
|
|
@ -163,7 +163,7 @@ int _wfd_dbus_object_removed(struct wfd_dbus *wfd_dbus,
|
||||||
size_t n_ifaces)
|
size_t n_ifaces)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
_sd_bus_message_unref_ sd_bus_message *m;
|
_sd_bus_message_unref_ sd_bus_message *m = NULL;
|
||||||
|
|
||||||
if(!wfd_dbus) {
|
if(!wfd_dbus) {
|
||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
|
@ -209,7 +209,7 @@ int _wfd_dbus_object_added(struct wfd_dbus *wfd_dbus,
|
||||||
size_t n_ifaces)
|
size_t n_ifaces)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
_sd_bus_message_unref_ sd_bus_message *m;
|
_sd_bus_message_unref_ sd_bus_message *m = NULL;
|
||||||
|
|
||||||
if(!wfd_dbus) {
|
if(!wfd_dbus) {
|
||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
|
@ -251,7 +251,7 @@ int _wfd_dbus_object_added(struct wfd_dbus *wfd_dbus,
|
||||||
|
|
||||||
int wfd_fn_sink_new(struct wfd_sink *s)
|
int wfd_fn_sink_new(struct wfd_sink *s)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
||||||
wfd_sink_get_label(s),
|
wfd_sink_get_label(s),
|
||||||
&path);
|
&path);
|
||||||
|
@ -264,7 +264,7 @@ int wfd_fn_sink_new(struct wfd_sink *s)
|
||||||
|
|
||||||
int wfd_fn_sink_free(struct wfd_sink *s)
|
int wfd_fn_sink_free(struct wfd_sink *s)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
||||||
wfd_sink_get_label(s),
|
wfd_sink_get_label(s),
|
||||||
&path);
|
&path);
|
||||||
|
@ -277,7 +277,7 @@ int wfd_fn_sink_free(struct wfd_sink *s)
|
||||||
|
|
||||||
int _wfd_fn_sink_properties_changed(struct wfd_sink *s, char **names)
|
int _wfd_fn_sink_properties_changed(struct wfd_sink *s, char **names)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r;
|
int r;
|
||||||
struct wfd_dbus *wfd_dbus = wfd_dbus_get();
|
struct wfd_dbus *wfd_dbus = wfd_dbus_get();
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ static int wfd_dbus_find_sink(sd_bus *bus,
|
||||||
|
|
||||||
int wfd_fn_session_new(struct wfd_session *s)
|
int wfd_fn_session_new(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r = wfd_dbus_get_session_path(s, &path);
|
int r = wfd_dbus_get_session_path(s, &path);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
return r;
|
return r;
|
||||||
|
@ -333,7 +333,7 @@ int wfd_fn_session_new(struct wfd_session *s)
|
||||||
|
|
||||||
int wfd_fn_session_free(struct wfd_session *s)
|
int wfd_fn_session_free(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r = wfd_dbus_get_session_path(s, &path);
|
int r = wfd_dbus_get_session_path(s, &path);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
return r;
|
return r;
|
||||||
|
@ -424,6 +424,30 @@ static int wfd_dbus_sink_start_session(sd_bus_message *m,
|
||||||
// return 0;
|
// return 0;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
static int wfd_dbus_sink_get_session(sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *reply,
|
||||||
|
void *userdata,
|
||||||
|
sd_bus_error *ret_error)
|
||||||
|
{
|
||||||
|
struct wfd_sink *s = userdata;
|
||||||
|
_shl_free_ char *session_path = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(!s->session) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = wfd_dbus_get_session_path(s->session, &session_path);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_bus_message_append(reply, "o", session_path);
|
||||||
|
}
|
||||||
|
|
||||||
static int wfd_dbus_sink_get_peer(sd_bus *bus,
|
static int wfd_dbus_sink_get_peer(sd_bus *bus,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
|
@ -433,7 +457,7 @@ static int wfd_dbus_sink_get_peer(sd_bus *bus,
|
||||||
sd_bus_error *ret_error)
|
sd_bus_error *ret_error)
|
||||||
{
|
{
|
||||||
struct wfd_sink *s = userdata;
|
struct wfd_sink *s = userdata;
|
||||||
_shl_free_ char *peer_path;
|
_shl_free_ char *peer_path = NULL;
|
||||||
int r = sd_bus_path_encode("/org/freedesktop/miracle/wifi/peer",
|
int r = sd_bus_path_encode("/org/freedesktop/miracle/wifi/peer",
|
||||||
s->label,
|
s->label,
|
||||||
&peer_path);
|
&peer_path);
|
||||||
|
@ -560,7 +584,7 @@ static int wfd_dbus_get_session_state(sd_bus *bus,
|
||||||
|
|
||||||
int _wfd_fn_session_properties_changed(struct wfd_session *s, char **names)
|
int _wfd_fn_session_properties_changed(struct wfd_session *s, char **names)
|
||||||
{
|
{
|
||||||
_shl_free_ char *path;
|
_shl_free_ char *path = NULL;
|
||||||
int r;
|
int r;
|
||||||
struct wfd_dbus *wfd_dbus = wfd_dbus_get();
|
struct wfd_dbus *wfd_dbus = wfd_dbus_get();
|
||||||
|
|
||||||
|
@ -591,6 +615,7 @@ static const sd_bus_vtable wfd_dbus_sink_vtable[] = {
|
||||||
/*SD_BUS_PROPERTY("VideoFormats", "a{sv}", wfd_dbus_sink_get_video_formats, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
/*SD_BUS_PROPERTY("VideoFormats", "a{sv}", wfd_dbus_sink_get_video_formats, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
||||||
/*SD_BUS_PROPERTY("HasAudio", "b", wfd_dbus_sink_has_audio, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
/*SD_BUS_PROPERTY("HasAudio", "b", wfd_dbus_sink_has_audio, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
||||||
/*SD_BUS_PROPERTY("HasVideo", "b", wfd_dbus_sink_has_video, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
/*SD_BUS_PROPERTY("HasVideo", "b", wfd_dbus_sink_has_video, 0, SD_BUS_VTABLE_PROPERTY_CONST),*/
|
||||||
|
SD_BUS_PROPERTY("Session", "o", wfd_dbus_sink_get_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("Peer", "o", wfd_dbus_sink_get_peer, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Peer", "o", wfd_dbus_sink_get_peer, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_VTABLE_END,
|
SD_BUS_VTABLE_END,
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,10 +30,13 @@ struct wfd_out_session
|
||||||
struct wfd_session parent;
|
struct wfd_session parent;
|
||||||
struct wfd_sink *sink;
|
struct wfd_sink *sink;
|
||||||
int fd;
|
int fd;
|
||||||
|
sd_event_source *gst_term_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[];
|
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[];
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int wfd_out_session_new(struct wfd_session **out, struct wfd_sink *sink)
|
int wfd_out_session_new(struct wfd_session **out, struct wfd_sink *sink)
|
||||||
{
|
{
|
||||||
struct wfd_out_session *s = calloc(1, sizeof(struct wfd_out_session));
|
struct wfd_out_session *s = calloc(1, sizeof(struct wfd_out_session));
|
||||||
|
@ -164,9 +167,14 @@ int wfd_out_session_initiate_io(struct wfd_session *s,
|
||||||
|
|
||||||
static void wfd_out_session_kill_gst(struct wfd_session *s)
|
static void wfd_out_session_kill_gst(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
if(-1 != s->stream.gst) {
|
pid_t pid;
|
||||||
kill(s->stream.gst, SIGTERM);
|
struct wfd_out_session *os = wfd_out_session(s);
|
||||||
s->stream.gst = -1;
|
if(os->gst_term_source) {
|
||||||
|
sd_event_source_get_child_pid(os->gst_term_source, &pid);
|
||||||
|
kill(pid, SIGTERM);
|
||||||
|
|
||||||
|
sd_event_source_set_userdata(os->gst_term_source, NULL);
|
||||||
|
os->gst_term_source = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,20 +199,15 @@ int wfd_out_session_teardown(struct wfd_session *s)
|
||||||
&(struct wfd_arg_list) wfd_arg_list(wfd_arg_cstr("TEARDOWN")));
|
&(struct wfd_arg_list) wfd_arg_list(wfd_arg_cstr("TEARDOWN")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wfd_out_session_end(struct wfd_session *s)
|
void wfd_out_session_destroy(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
struct wfd_out_session *os = wfd_out_session(s);
|
struct wfd_out_session *os = wfd_out_session(s);
|
||||||
|
|
||||||
wfd_out_session_kill_gst(s);
|
|
||||||
|
|
||||||
if(0 <= os->fd) {
|
if(0 <= os->fd) {
|
||||||
close(os->fd);
|
close(os->fd);
|
||||||
os->fd = -1;
|
os->fd = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void wfd_out_session_distruct(struct wfd_session *s)
|
wfd_out_session_kill_gst(s);
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wfd_out_session_initiate_request(struct wfd_session *s)
|
int wfd_out_session_initiate_request(struct wfd_session *s)
|
||||||
|
@ -305,7 +308,6 @@ static int wfd_out_session_request_get_parameter(struct wfd_session *s,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
wfd_session_end(s);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +427,6 @@ static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out)
|
||||||
char port[10];
|
char port[10];
|
||||||
char * args[] = {
|
char * args[] = {
|
||||||
"gst-launch-1.0",
|
"gst-launch-1.0",
|
||||||
"-v",
|
|
||||||
"ximagesrc",
|
"ximagesrc",
|
||||||
"use-damage=false",
|
"use-damage=false",
|
||||||
"show-pointer=false",
|
"show-pointer=false",
|
||||||
|
@ -473,9 +474,21 @@ static int wfd_out_session_handle_gst_term(sd_event_source *source,
|
||||||
const siginfo_t *si,
|
const siginfo_t *si,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
|
struct wfd_out_session *os = userdata;
|
||||||
|
|
||||||
log_trace("gst-launch(%d) terminated", si->si_pid);
|
log_trace("gst-launch(%d) terminated", si->si_pid);
|
||||||
|
|
||||||
wfd_session_end(userdata);
|
sd_event_source_unref(source);
|
||||||
|
|
||||||
|
if(!os) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
os->gst_term_source = NULL;
|
||||||
|
|
||||||
|
if(WFD_SESSION_STATE_PAUSED != wfd_session(os)->state) {
|
||||||
|
wfd_session_teardown(wfd_session(os));
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +543,7 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||||
struct rtsp_message *req,
|
struct rtsp_message *req,
|
||||||
struct rtsp_message **out_rep)
|
struct rtsp_message **out_rep)
|
||||||
{
|
{
|
||||||
_shl_free_ char *v;
|
_shl_free_ char *v = NULL;
|
||||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
pid_t gst;
|
pid_t gst;
|
||||||
int r, status;
|
int r, status;
|
||||||
|
@ -564,22 +577,21 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_event_add_child(ctl_wfd_get_loop(),
|
r = sd_event_add_child(ctl_wfd_get_loop(),
|
||||||
NULL,
|
&wfd_out_session(s)->gst_term_source,
|
||||||
gst, WEXITED,
|
gst, WEXITED,
|
||||||
wfd_out_session_handle_gst_term,
|
wfd_out_session_handle_gst_term,
|
||||||
s);
|
s);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
kill(gst, SIGKILL);
|
kill(gst, SIGKILL);
|
||||||
waitpid(gst, &status, WNOHANG);
|
waitpid(gst, &status, WNOHANG);
|
||||||
return r;
|
wfd_session_teardown(s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*out_rep = m;
|
||||||
|
m = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->stream.gst = gst;
|
return r;
|
||||||
|
|
||||||
*out_rep = m;
|
|
||||||
m = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
|
@ -698,7 +710,7 @@ static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
||||||
const struct wfd_arg_list *args,
|
const struct wfd_arg_list *args,
|
||||||
struct rtsp_message **out)
|
struct rtsp_message **out)
|
||||||
{
|
{
|
||||||
_rtsp_message_unref_ struct rtsp_message *m;
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
_shl_free_ char *body = NULL;
|
_shl_free_ char *body = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ extern int wfd_out_session_resume(struct wfd_session *);
|
||||||
extern int wfd_out_session_pause(struct wfd_session *);
|
extern int wfd_out_session_pause(struct wfd_session *);
|
||||||
extern int wfd_out_session_teardown(struct wfd_session *);
|
extern int wfd_out_session_teardown(struct wfd_session *);
|
||||||
extern void wfd_out_session_end(struct wfd_session *);
|
extern void wfd_out_session_end(struct wfd_session *);
|
||||||
extern void wfd_out_session_distruct(struct wfd_session *);
|
extern void wfd_out_session_destroy(struct wfd_session *);
|
||||||
|
|
||||||
const struct wfd_session_vtable session_vtbl[] = {
|
const struct wfd_session_vtable session_vtbl[] = {
|
||||||
[WFD_SESSION_DIR_OUT] = {
|
[WFD_SESSION_DIR_OUT] = {
|
||||||
|
@ -53,8 +53,7 @@ const struct wfd_session_vtable session_vtbl[] = {
|
||||||
.resume = wfd_out_session_resume,
|
.resume = wfd_out_session_resume,
|
||||||
.pause = wfd_out_session_pause,
|
.pause = wfd_out_session_pause,
|
||||||
.teardown = wfd_out_session_teardown,
|
.teardown = wfd_out_session_teardown,
|
||||||
.end = wfd_out_session_end,
|
.destroy = wfd_out_session_destroy,
|
||||||
.distruct = wfd_out_session_distruct,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,6 +177,9 @@ int wfd_session_teardown(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
assert(wfd_is_session(s));
|
assert(wfd_is_session(s));
|
||||||
|
|
||||||
|
/* notify and detach from sink */
|
||||||
|
wfd_fn_out_session_ended(s);
|
||||||
|
|
||||||
if(wfd_session_is_established(s)) {
|
if(wfd_session_is_established(s)) {
|
||||||
if(!session_vtbl[s->dir].teardown) {
|
if(!session_vtbl[s->dir].teardown) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -186,41 +188,21 @@ int wfd_session_teardown(struct wfd_session *s)
|
||||||
return session_vtbl[s->dir].teardown(s);;
|
return session_vtbl[s->dir].teardown(s);;
|
||||||
}
|
}
|
||||||
|
|
||||||
wfd_session_end(s);
|
wfd_session_free(s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wfd_session_end(struct wfd_session *s)
|
|
||||||
{
|
|
||||||
assert(wfd_is_session(s));
|
|
||||||
|
|
||||||
if(WFD_SESSION_STATE_NULL == s->state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("session %lu ended", s->id);
|
|
||||||
|
|
||||||
wfd_session_set_state(s, WFD_SESSION_STATE_NULL);
|
|
||||||
|
|
||||||
(*session_vtbl[s->dir].end)(s);
|
|
||||||
|
|
||||||
if(s->rtsp) {
|
|
||||||
rtsp_unref(s->rtsp);
|
|
||||||
s->rtsp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wfd_is_out_session(s)) {
|
|
||||||
wfd_fn_out_session_ended(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wfd_session_free(struct wfd_session *s)
|
void wfd_session_free(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
if(!s) {
|
if(!s) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(session_vtbl[s->dir].destroy) {
|
||||||
|
(*session_vtbl[s->dir].destroy)(s);
|
||||||
|
}
|
||||||
|
|
||||||
if(s->vformats) {
|
if(s->vformats) {
|
||||||
wfd_video_formats_free(s->vformats);
|
wfd_video_formats_free(s->vformats);
|
||||||
s->vformats = NULL;
|
s->vformats = NULL;
|
||||||
|
@ -236,16 +218,15 @@ void wfd_session_free(struct wfd_session *s)
|
||||||
s->stream.url = NULL;
|
s->stream.url = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s->rtsp) {
|
||||||
|
rtsp_unref(s->rtsp);
|
||||||
|
s->rtsp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
s->rtp_ports[0] = 0;
|
s->rtp_ports[0] = 0;
|
||||||
s->rtp_ports[1] = 0;
|
s->rtp_ports[1] = 0;
|
||||||
s->last_request = RTSP_M_UNKNOWN;
|
s->last_request = RTSP_M_UNKNOWN;
|
||||||
|
|
||||||
wfd_session_end(s);
|
|
||||||
|
|
||||||
if(session_vtbl[s->dir].distruct) {
|
|
||||||
(*session_vtbl[s->dir].distruct)(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,6 +382,10 @@ static int wfd_session_post_handle_request_n_reply(struct wfd_session *s,
|
||||||
if(RTSP_M_UNKNOWN != next_request) {
|
if(RTSP_M_UNKNOWN != next_request) {
|
||||||
return wfd_session_request(s, next_request, req_args);
|
return wfd_session_request(s, next_request, req_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(WFD_SESSION_STATE_TEARING_DOWN == new_state) {
|
||||||
|
wfd_fn_out_session_ended(s);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -454,7 +439,7 @@ static int wfd_session_handle_request(struct rtsp *bus,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
wfd_session_end(s);
|
wfd_session_teardown(s);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -498,7 +483,8 @@ static int wfd_session_handle_reply(struct rtsp *bus,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
wfd_session_end(s);
|
wfd_session_teardown(s);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,6 +538,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
||||||
_rtsp_unref_ struct rtsp *rtsp = NULL;
|
_rtsp_unref_ struct rtsp *rtsp = NULL;
|
||||||
|
|
||||||
sd_event_source_set_enabled(source, SD_EVENT_OFF);
|
sd_event_source_set_enabled(source, SD_EVENT_OFF);
|
||||||
|
sd_event_source_unref(source);
|
||||||
|
|
||||||
if (mask & EPOLLERR) {
|
if (mask & EPOLLERR) {
|
||||||
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
|
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
|
||||||
|
@ -597,7 +584,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (0 > r) {
|
if (0 > r) {
|
||||||
wfd_session_end(s);
|
wfd_session_teardown(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#define wfd_out_session(s) (assert(wfd_is_out_session(s)), (struct wfd_out_session *) (s))
|
#define wfd_out_session(s) (assert(wfd_is_out_session(s)), (struct wfd_out_session *) (s))
|
||||||
#define wfd_in_session(s) (assert(wfd_is_in_session(s)), (struct wfd_in_session *) (s))
|
#define wfd_in_session(s) (assert(wfd_is_in_session(s)), (struct wfd_in_session *) (s))
|
||||||
#define wfd_session_is_destructed(s) (!(s) || (s)->destructed)
|
|
||||||
|
|
||||||
struct wfd_session;
|
struct wfd_session;
|
||||||
struct wfd_sink;
|
struct wfd_sink;
|
||||||
|
@ -89,8 +88,7 @@ struct wfd_session_vtable
|
||||||
int (*resume)(struct wfd_session *);
|
int (*resume)(struct wfd_session *);
|
||||||
int (*pause)(struct wfd_session *);
|
int (*pause)(struct wfd_session *);
|
||||||
int (*teardown)(struct wfd_session *);
|
int (*teardown)(struct wfd_session *);
|
||||||
void (*end)(struct wfd_session *s);
|
void (*destroy)(struct wfd_session *s);
|
||||||
void (*distruct)(struct wfd_session *s);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wfd_session
|
struct wfd_session
|
||||||
|
@ -110,7 +108,6 @@ struct wfd_session
|
||||||
enum wfd_stream_id id;
|
enum wfd_stream_id id;
|
||||||
char *url;
|
char *url;
|
||||||
uint16_t rtp_port;
|
uint16_t rtp_port;
|
||||||
pid_t gst;
|
|
||||||
} stream;
|
} stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,34 @@
|
||||||
#include "ctl.h"
|
#include "ctl.h"
|
||||||
#include "wfd-dbus.h"
|
#include "wfd-dbus.h"
|
||||||
|
|
||||||
|
static int wfd_sink_set_session(struct wfd_sink *sink,
|
||||||
|
struct wfd_session *session)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if(sink->session == session) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
r = ctl_wfd_add_session(ctl_wfd_get(), session);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sink->session) {
|
||||||
|
ctl_wfd_remove_session_by_id(ctl_wfd_get(),
|
||||||
|
wfd_session_get_id(sink->session),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
sink->session = session;
|
||||||
|
wfd_fn_sink_properties_changed(sink, "Session");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int wfd_sink_new(struct wfd_sink **out,
|
int wfd_sink_new(struct wfd_sink **out,
|
||||||
struct ctl_peer *peer,
|
struct ctl_peer *peer,
|
||||||
union wfd_sube *sube)
|
union wfd_sube *sube)
|
||||||
|
@ -55,12 +83,16 @@ int wfd_sink_new(struct wfd_sink **out,
|
||||||
|
|
||||||
void wfd_sink_free(struct wfd_sink *sink)
|
void wfd_sink_free(struct wfd_sink *sink)
|
||||||
{
|
{
|
||||||
|
struct wfd_session *s;
|
||||||
|
|
||||||
if(!sink) {
|
if(!sink) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sink->session) {
|
if(sink->session) {
|
||||||
wfd_session_free(sink->session);
|
s = sink->session;
|
||||||
|
wfd_sink_set_session(sink, NULL);
|
||||||
|
wfd_session_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sink->label) {
|
if(sink->label) {
|
||||||
|
@ -107,7 +139,7 @@ int wfd_sink_start_session(struct wfd_sink *sink, struct wfd_session **out)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = ctl_wfd_add_session(ctl_wfd_get(), s);
|
r = wfd_sink_set_session(sink, s);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -121,43 +153,13 @@ int wfd_sink_start_session(struct wfd_sink *sink, struct wfd_session **out)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_sink_defered_session_cleanup(sd_event_source *source,
|
|
||||||
uint64_t used,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct wfd_session *s = userdata;
|
|
||||||
|
|
||||||
sd_event_source_set_enabled(source, false);
|
|
||||||
|
|
||||||
ctl_wfd_remove_session_by_id(ctl_wfd_get(),
|
|
||||||
wfd_session_get_id(s),
|
|
||||||
NULL);
|
|
||||||
wfd_session_free(s);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wfd_fn_out_session_ended(struct wfd_session *s)
|
int wfd_fn_out_session_ended(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
struct wfd_sink *sink;
|
|
||||||
uint64_t now = 0;
|
|
||||||
|
|
||||||
assert(wfd_is_out_session(s));
|
assert(wfd_is_out_session(s));
|
||||||
|
|
||||||
sink = wfd_out_session_get_sink(s);
|
wfd_sink_set_session(wfd_out_session_get_sink(s), NULL);
|
||||||
sink->session = NULL;
|
|
||||||
|
|
||||||
wfd_fn_sink_properties_changed(sink, "Session");
|
return 0;
|
||||||
|
|
||||||
sd_event_now(ctl_wfd_get_loop(), CLOCK_MONOTONIC, &now);
|
|
||||||
|
|
||||||
return sd_event_add_time(ctl_wfd_get_loop(),
|
|
||||||
NULL,
|
|
||||||
CLOCK_MONOTONIC,
|
|
||||||
200 * 1000 + now,
|
|
||||||
0,
|
|
||||||
wfd_sink_defered_session_cleanup,
|
|
||||||
s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wfd_sink_is_session_started(struct wfd_sink *sink)
|
bool wfd_sink_is_session_started(struct wfd_sink *sink)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <systemd/sd-event.h>
|
#include <systemd/sd-event.h>
|
||||||
#include "ctl.h"
|
#include "ctl.h"
|
||||||
#include "wfd.h"
|
#include "wfd.h"
|
||||||
|
@ -71,21 +72,25 @@ error:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ctl_wfd_destroy(struct ctl_wfd *wfd)
|
|
||||||
{
|
|
||||||
ctl_wifi_free(wfd->wifi);
|
|
||||||
wfd->wifi = NULL;
|
|
||||||
shl_htable_clear_str(&wfd->sinks, NULL, NULL);
|
|
||||||
shl_htable_clear_u64(&wfd->sessions, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ctl_wfd_free(struct ctl_wfd *wfd)
|
static void ctl_wfd_free(struct ctl_wfd *wfd)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if(!wfd) {
|
if(!wfd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctl_wfd_destroy(wfd);
|
ctl_wifi_free(wfd->wifi);
|
||||||
|
wfd->wifi = NULL;
|
||||||
|
shl_htable_clear_str(&wfd->sinks, NULL, NULL);
|
||||||
|
shl_htable_clear_u64(&wfd->sessions, NULL, NULL);
|
||||||
|
|
||||||
|
for(i = 0; i < SHL_ARRAY_LENGTH(wfd->signal_sources); ++ i) {
|
||||||
|
if(wfd->signal_sources[i]) {
|
||||||
|
sd_event_source_set_enabled(wfd->signal_sources[i], SD_EVENT_OFF);
|
||||||
|
sd_event_source_unref(wfd->signal_sources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(wfd->loop) {
|
if(wfd->loop) {
|
||||||
sd_event_unref(wfd->loop);
|
sd_event_unref(wfd->loop);
|
||||||
|
@ -99,7 +104,7 @@ int ctl_wfd_add_sink(struct ctl_wfd *wfd,
|
||||||
union wfd_sube *sube,
|
union wfd_sube *sube,
|
||||||
struct wfd_sink **out)
|
struct wfd_sink **out)
|
||||||
{
|
{
|
||||||
_wfd_sink_free_ struct wfd_sink *s;
|
_wfd_sink_free_ struct wfd_sink *s = NULL;
|
||||||
int r = shl_htable_lookup_str(&wfd->sinks,
|
int r = shl_htable_lookup_str(&wfd->sinks,
|
||||||
p->label,
|
p->label,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -223,7 +228,11 @@ int ctl_wfd_remove_session_by_id(struct ctl_wfd *wfd,
|
||||||
static int ctl_wfd_fetch_info(sd_event_source *s, void *userdata)
|
static int ctl_wfd_fetch_info(sd_event_source *s, void *userdata)
|
||||||
{
|
{
|
||||||
struct ctl_wfd *wfd = userdata;
|
struct ctl_wfd *wfd = userdata;
|
||||||
int r = ctl_wifi_fetch(wfd->wifi);
|
int r;
|
||||||
|
|
||||||
|
sd_event_source_unref(s);
|
||||||
|
|
||||||
|
r = ctl_wifi_fetch(wfd->wifi);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
log_warning("failed to fetch information about links and peers: %s",
|
log_warning("failed to fetch information about links and peers: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
@ -238,7 +247,8 @@ static int ctl_wfd_handle_signal(sd_event_source *s,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct ctl_wfd *wfd = userdata;
|
struct ctl_wfd *wfd = userdata;
|
||||||
ctl_wfd_destroy(wfd);
|
|
||||||
|
sd_event_source_set_enabled(s, false);
|
||||||
|
|
||||||
return sd_event_exit(wfd->loop, 0);
|
return sd_event_exit(wfd->loop, 0);
|
||||||
}
|
}
|
||||||
|
@ -246,10 +256,12 @@ static int ctl_wfd_handle_signal(sd_event_source *s,
|
||||||
static int ctl_wfd_init(struct ctl_wfd *wfd, sd_bus *bus)
|
static int ctl_wfd_init(struct ctl_wfd *wfd, sd_bus *bus)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
const int signals[] = { SIGINT, SIGHUP, SIGQUIT, SIGTERM };
|
const int signals[SHL_ARRAY_LENGTH(wfd->signal_sources)] = {
|
||||||
|
SIGINT, SIGHUP, SIGQUIT, SIGTERM
|
||||||
|
};
|
||||||
struct ctl_wifi *wifi;
|
struct ctl_wifi *wifi;
|
||||||
|
|
||||||
for(i = 0; i < SHL_ARRAY_LENGTH(signals); i ++) {
|
for(i = 0; i < SHL_ARRAY_LENGTH(wfd->signal_sources); i ++) {
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
sigaddset(&mask, signals[i]);
|
sigaddset(&mask, signals[i]);
|
||||||
|
@ -259,7 +271,7 @@ static int ctl_wfd_init(struct ctl_wfd *wfd, sd_bus *bus)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_event_add_signal(wfd->loop,
|
r = sd_event_add_signal(wfd->loop,
|
||||||
NULL,
|
&wfd->signal_sources[i],
|
||||||
signals[i],
|
signals[i],
|
||||||
ctl_wfd_handle_signal,
|
ctl_wfd_handle_signal,
|
||||||
wfd);
|
wfd);
|
||||||
|
@ -286,11 +298,6 @@ end:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ctl_wfd_run(struct ctl_wfd *wfd)
|
|
||||||
{
|
|
||||||
return sd_event_loop(wfd->loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callbacks from ctl-src */
|
/* Callbacks from ctl-src */
|
||||||
void wfd_fn_src_connected(struct wfd_src *s)
|
void wfd_fn_src_connected(struct wfd_src *s)
|
||||||
{
|
{
|
||||||
|
@ -366,12 +373,7 @@ void ctl_fn_peer_free(struct ctl_peer *p)
|
||||||
|
|
||||||
label = strdup(s->label);
|
label = strdup(s->label);
|
||||||
|
|
||||||
r = wfd_fn_sink_free(s);
|
wfd_fn_sink_free(s);
|
||||||
if(0 > r) {
|
|
||||||
log_warning("failed to unpublish removed sink (%s): %s",
|
|
||||||
wfd_sink_get_label(s),
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
wfd_sink_free(s);
|
wfd_sink_free(s);
|
||||||
|
|
||||||
|
@ -417,6 +419,7 @@ void cli_fn_help()
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
sd_event *loop;
|
sd_event *loop;
|
||||||
sd_bus *bus;
|
sd_bus *bus;
|
||||||
|
|
||||||
|
@ -457,25 +460,26 @@ int main(int argc, char **argv)
|
||||||
r = wfd_dbus_expose(wfd_dbus);
|
r = wfd_dbus_expose(wfd_dbus);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
log_warning("unabled to publish WFD service: %s", strerror(errno));
|
log_warning("unabled to publish WFD service: %s", strerror(errno));
|
||||||
goto free_ctl_wfd;
|
goto free_wfd_dbus;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = ctl_wfd_run(wfd);
|
r = sd_event_loop(loop);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
log_warning("unabled to keep WFD service running: %s", strerror(errno));
|
log_warning("unabled to keep WFD service running: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_wfd_dbus:
|
||||||
wfd_dbus_free(wfd_dbus);
|
wfd_dbus_free(wfd_dbus);
|
||||||
wfd_dbus = NULL;
|
wfd_dbus = NULL;
|
||||||
|
|
||||||
free_ctl_wfd:
|
free_ctl_wfd:
|
||||||
ctl_wfd_free(wfd);
|
ctl_wfd_free(wfd);
|
||||||
wfd = NULL;
|
wfd = NULL;
|
||||||
bus_detach_event:
|
bus_detach_event:
|
||||||
sd_bus_detach_event(bus);
|
sd_bus_detach_event(bus);
|
||||||
unref_bus:
|
unref_bus:
|
||||||
sd_bus_unref(bus);
|
sd_bus_flush_close_unref(bus);
|
||||||
unref_loop:
|
unref_loop:
|
||||||
|
sd_event_run(loop, 0);
|
||||||
sd_event_unref(loop);
|
sd_event_unref(loop);
|
||||||
end:
|
end:
|
||||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in a new issue