mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-13 10:01:55 +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()
|
||||
{
|
||||
kill 0
|
||||
set -x
|
||||
for (( i=${#cleanup[@]}-1; i>=0; --i )); do
|
||||
eval ${cleanup[$i]} || true
|
||||
set +e
|
||||
while (( 0 != ${#cleanup[@]} )); do
|
||||
eval ${cleanup[${#cleanup[@]}-1]}
|
||||
unset cleanup[${#cleanup[@]}-1]
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,14 @@ cleanup_push()
|
|||
cleanup+=("$*")
|
||||
}
|
||||
|
||||
nm_manage()
|
||||
{
|
||||
set_prop org.freedesktop.NetworkManager \
|
||||
/org/freedesktop/NetworkManager/Devices/"$nm_link_index" \
|
||||
org.freedesktop.NetworkManager.Device \
|
||||
Managed b true
|
||||
}
|
||||
|
||||
link_unmanage()
|
||||
{
|
||||
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.Device \
|
||||
Managed b false
|
||||
cleanup_push nm_manage
|
||||
set_prop org.freedesktop.miracle.wifi \
|
||||
/org/freedesktop/miracle/wifi/link/$link_index \
|
||||
org.freedesktop.miracle.wifi.Link \
|
||||
|
@ -179,6 +188,8 @@ get_prop org.freedesktop.miracle.wifi \
|
|||
org.freedesktop.miracle.wifi.Peer \
|
||||
Interface p2p_iface
|
||||
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
|
||||
echo please run miracle-wfdctl manually
|
||||
sleep 3
|
||||
|
|
|
@ -198,6 +198,8 @@ struct wfd_sink
|
|||
union wfd_sube dev_info;
|
||||
char *label;
|
||||
struct wfd_session *session;
|
||||
|
||||
sd_event_source *session_cleanup_source;
|
||||
};
|
||||
|
||||
int wfd_sink_new(struct wfd_sink **out,
|
||||
|
@ -237,6 +239,8 @@ struct ctl_wfd
|
|||
struct shl_htable sessions;
|
||||
size_t n_sessions;
|
||||
uint64_t id_pool;
|
||||
|
||||
sd_event_source *signal_sources[4];
|
||||
};
|
||||
|
||||
struct ctl_wfd * ctl_wfd_get();
|
||||
|
|
|
@ -163,7 +163,7 @@ int _wfd_dbus_object_removed(struct wfd_dbus *wfd_dbus,
|
|||
size_t n_ifaces)
|
||||
{
|
||||
int i, r;
|
||||
_sd_bus_message_unref_ sd_bus_message *m;
|
||||
_sd_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
|
||||
if(!wfd_dbus) {
|
||||
return -ECANCELED;
|
||||
|
@ -209,7 +209,7 @@ int _wfd_dbus_object_added(struct wfd_dbus *wfd_dbus,
|
|||
size_t n_ifaces)
|
||||
{
|
||||
int i, r;
|
||||
_sd_bus_message_unref_ sd_bus_message *m;
|
||||
_sd_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
|
||||
if(!wfd_dbus) {
|
||||
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)
|
||||
{
|
||||
_shl_free_ char *path;
|
||||
_shl_free_ char *path = NULL;
|
||||
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
||||
wfd_sink_get_label(s),
|
||||
&path);
|
||||
|
@ -264,7 +264,7 @@ int wfd_fn_sink_new(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",
|
||||
wfd_sink_get_label(s),
|
||||
&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)
|
||||
{
|
||||
_shl_free_ char *path;
|
||||
_shl_free_ char *path = NULL;
|
||||
int r;
|
||||
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)
|
||||
{
|
||||
_shl_free_ char *path;
|
||||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_session_path(s, &path);
|
||||
if(0 > 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)
|
||||
{
|
||||
_shl_free_ char *path;
|
||||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_session_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
|
@ -424,6 +424,30 @@ static int wfd_dbus_sink_start_session(sd_bus_message *m,
|
|||
// 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,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
|
@ -433,7 +457,7 @@ static int wfd_dbus_sink_get_peer(sd_bus *bus,
|
|||
sd_bus_error *ret_error)
|
||||
{
|
||||
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",
|
||||
s->label,
|
||||
&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)
|
||||
{
|
||||
_shl_free_ char *path;
|
||||
_shl_free_ char *path = NULL;
|
||||
int r;
|
||||
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("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("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_VTABLE_END,
|
||||
};
|
||||
|
|
|
@ -30,10 +30,13 @@ struct wfd_out_session
|
|||
struct wfd_session parent;
|
||||
struct wfd_sink *sink;
|
||||
int fd;
|
||||
sd_event_source *gst_term_source;
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(-1 != s->stream.gst) {
|
||||
kill(s->stream.gst, SIGTERM);
|
||||
s->stream.gst = -1;
|
||||
pid_t pid;
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
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")));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
wfd_out_session_kill_gst(s);
|
||||
|
||||
if(0 <= os->fd) {
|
||||
close(os->fd);
|
||||
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)
|
||||
|
@ -305,7 +308,6 @@ static int wfd_out_session_request_get_parameter(struct wfd_session *s,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
wfd_session_end(s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -425,7 +427,6 @@ static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out)
|
|||
char port[10];
|
||||
char * args[] = {
|
||||
"gst-launch-1.0",
|
||||
"-v",
|
||||
"ximagesrc",
|
||||
"use-damage=false",
|
||||
"show-pointer=false",
|
||||
|
@ -473,9 +474,21 @@ static int wfd_out_session_handle_gst_term(sd_event_source *source,
|
|||
const siginfo_t *si,
|
||||
void *userdata)
|
||||
{
|
||||
struct wfd_out_session *os = userdata;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -530,7 +543,7 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
{
|
||||
_shl_free_ char *v;
|
||||
_shl_free_ char *v = NULL;
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
pid_t gst;
|
||||
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(),
|
||||
NULL,
|
||||
&wfd_out_session(s)->gst_term_source,
|
||||
gst, WEXITED,
|
||||
wfd_out_session_handle_gst_term,
|
||||
s);
|
||||
if(0 > r) {
|
||||
kill(gst, SIGKILL);
|
||||
waitpid(gst, &status, WNOHANG);
|
||||
return r;
|
||||
wfd_session_teardown(s);
|
||||
}
|
||||
|
||||
s->stream.gst = gst;
|
||||
|
||||
else {
|
||||
*out_rep = m;
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
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,
|
||||
struct rtsp_message **out)
|
||||
{
|
||||
_rtsp_message_unref_ struct rtsp_message *m;
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
_shl_free_ char *body = NULL;
|
||||
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_teardown(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[] = {
|
||||
[WFD_SESSION_DIR_OUT] = {
|
||||
|
@ -53,8 +53,7 @@ const struct wfd_session_vtable session_vtbl[] = {
|
|||
.resume = wfd_out_session_resume,
|
||||
.pause = wfd_out_session_pause,
|
||||
.teardown = wfd_out_session_teardown,
|
||||
.end = wfd_out_session_end,
|
||||
.distruct = wfd_out_session_distruct,
|
||||
.destroy = wfd_out_session_destroy,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -178,6 +177,9 @@ int wfd_session_teardown(struct wfd_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(!session_vtbl[s->dir].teardown) {
|
||||
return 0;
|
||||
|
@ -186,41 +188,21 @@ int wfd_session_teardown(struct wfd_session *s)
|
|||
return session_vtbl[s->dir].teardown(s);;
|
||||
}
|
||||
|
||||
wfd_session_end(s);
|
||||
wfd_session_free(s);
|
||||
|
||||
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)
|
||||
{
|
||||
if(!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(session_vtbl[s->dir].destroy) {
|
||||
(*session_vtbl[s->dir].destroy)(s);
|
||||
}
|
||||
|
||||
if(s->vformats) {
|
||||
wfd_video_formats_free(s->vformats);
|
||||
s->vformats = NULL;
|
||||
|
@ -236,16 +218,15 @@ void wfd_session_free(struct wfd_session *s)
|
|||
s->stream.url = NULL;
|
||||
}
|
||||
|
||||
if(s->rtsp) {
|
||||
rtsp_unref(s->rtsp);
|
||||
s->rtsp = NULL;
|
||||
}
|
||||
|
||||
s->rtp_ports[0] = 0;
|
||||
s->rtp_ports[1] = 0;
|
||||
s->last_request = RTSP_M_UNKNOWN;
|
||||
|
||||
wfd_session_end(s);
|
||||
|
||||
if(session_vtbl[s->dir].distruct) {
|
||||
(*session_vtbl[s->dir].distruct)(s);
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
@ -402,6 +383,10 @@ static int wfd_session_post_handle_request_n_reply(struct wfd_session *s,
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -454,7 +439,7 @@ static int wfd_session_handle_request(struct rtsp *bus,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
wfd_session_end(s);
|
||||
wfd_session_teardown(s);
|
||||
|
||||
return r;
|
||||
|
||||
|
@ -498,7 +483,8 @@ static int wfd_session_handle_reply(struct rtsp *bus,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
wfd_session_end(s);
|
||||
wfd_session_teardown(s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -552,6 +538,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
|||
_rtsp_unref_ struct rtsp *rtsp = NULL;
|
||||
|
||||
sd_event_source_set_enabled(source, SD_EVENT_OFF);
|
||||
sd_event_source_unref(source);
|
||||
|
||||
if (mask & EPOLLERR) {
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
|
||||
|
@ -597,7 +584,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
|||
|
||||
end:
|
||||
if (0 > r) {
|
||||
wfd_session_end(s);
|
||||
wfd_session_teardown(s);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#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_session_is_destructed(s) (!(s) || (s)->destructed)
|
||||
|
||||
struct wfd_session;
|
||||
struct wfd_sink;
|
||||
|
@ -89,8 +88,7 @@ struct wfd_session_vtable
|
|||
int (*resume)(struct wfd_session *);
|
||||
int (*pause)(struct wfd_session *);
|
||||
int (*teardown)(struct wfd_session *);
|
||||
void (*end)(struct wfd_session *s);
|
||||
void (*distruct)(struct wfd_session *s);
|
||||
void (*destroy)(struct wfd_session *s);
|
||||
};
|
||||
|
||||
struct wfd_session
|
||||
|
@ -110,7 +108,6 @@ struct wfd_session
|
|||
enum wfd_stream_id id;
|
||||
char *url;
|
||||
uint16_t rtp_port;
|
||||
pid_t gst;
|
||||
} stream;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,34 @@
|
|||
#include "ctl.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,
|
||||
struct ctl_peer *peer,
|
||||
union wfd_sube *sube)
|
||||
|
@ -55,12 +83,16 @@ int wfd_sink_new(struct wfd_sink **out,
|
|||
|
||||
void wfd_sink_free(struct wfd_sink *sink)
|
||||
{
|
||||
struct wfd_session *s;
|
||||
|
||||
if(!sink) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(sink->session) {
|
||||
wfd_session_free(sink->session);
|
||||
s = sink->session;
|
||||
wfd_sink_set_session(sink, NULL);
|
||||
wfd_session_free(s);
|
||||
}
|
||||
|
||||
if(sink->label) {
|
||||
|
@ -107,7 +139,7 @@ int wfd_sink_start_session(struct wfd_sink *sink, struct wfd_session **out)
|
|||
return r;
|
||||
}
|
||||
|
||||
r = ctl_wfd_add_session(ctl_wfd_get(), s);
|
||||
r = wfd_sink_set_session(sink, s);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
}
|
||||
|
@ -121,43 +153,13 @@ int wfd_sink_start_session(struct wfd_sink *sink, struct wfd_session **out)
|
|||
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)
|
||||
{
|
||||
struct wfd_sink *sink;
|
||||
uint64_t now = 0;
|
||||
|
||||
assert(wfd_is_out_session(s));
|
||||
|
||||
sink = wfd_out_session_get_sink(s);
|
||||
sink->session = NULL;
|
||||
wfd_sink_set_session(wfd_out_session_get_sink(s), NULL);
|
||||
|
||||
wfd_fn_sink_properties_changed(sink, "Session");
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool wfd_sink_is_session_started(struct wfd_sink *sink)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <systemd/sd-event.h>
|
||||
#include "ctl.h"
|
||||
#include "wfd.h"
|
||||
|
@ -71,21 +72,25 @@ error:
|
|||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!wfd) {
|
||||
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) {
|
||||
sd_event_unref(wfd->loop);
|
||||
|
@ -99,7 +104,7 @@ int ctl_wfd_add_sink(struct ctl_wfd *wfd,
|
|||
union wfd_sube *sube,
|
||||
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,
|
||||
p->label,
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
log_warning("failed to fetch information about links and peers: %s",
|
||||
strerror(errno));
|
||||
|
@ -238,7 +247,8 @@ static int ctl_wfd_handle_signal(sd_event_source *s,
|
|||
void *userdata)
|
||||
{
|
||||
struct ctl_wfd *wfd = userdata;
|
||||
ctl_wfd_destroy(wfd);
|
||||
|
||||
sd_event_source_set_enabled(s, false);
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
for(i = 0; i < SHL_ARRAY_LENGTH(signals); i ++) {
|
||||
for(i = 0; i < SHL_ARRAY_LENGTH(wfd->signal_sources); i ++) {
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
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,
|
||||
NULL,
|
||||
&wfd->signal_sources[i],
|
||||
signals[i],
|
||||
ctl_wfd_handle_signal,
|
||||
wfd);
|
||||
|
@ -286,11 +298,6 @@ end:
|
|||
return r;
|
||||
}
|
||||
|
||||
int ctl_wfd_run(struct ctl_wfd *wfd)
|
||||
{
|
||||
return sd_event_loop(wfd->loop);
|
||||
}
|
||||
|
||||
/* Callbacks from ctl-src */
|
||||
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);
|
||||
|
||||
r = 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_fn_sink_free(s);
|
||||
|
||||
wfd_sink_free(s);
|
||||
|
||||
|
@ -417,6 +419,7 @@ void cli_fn_help()
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
|
||||
sd_event *loop;
|
||||
sd_bus *bus;
|
||||
|
||||
|
@ -457,25 +460,26 @@ int main(int argc, char **argv)
|
|||
r = wfd_dbus_expose(wfd_dbus);
|
||||
if(0 > r) {
|
||||
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) {
|
||||
log_warning("unabled to keep WFD service running: %s", strerror(errno));
|
||||
}
|
||||
|
||||
free_wfd_dbus:
|
||||
wfd_dbus_free(wfd_dbus);
|
||||
wfd_dbus = NULL;
|
||||
|
||||
free_ctl_wfd:
|
||||
ctl_wfd_free(wfd);
|
||||
wfd = NULL;
|
||||
bus_detach_event:
|
||||
sd_bus_detach_event(bus);
|
||||
unref_bus:
|
||||
sd_bus_unref(bus);
|
||||
sd_bus_flush_close_unref(bus);
|
||||
unref_loop:
|
||||
sd_event_run(loop, 0);
|
||||
sd_event_unref(loop);
|
||||
end:
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
|
|
Loading…
Reference in a new issue