mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
module-rtp: improve session setup
This commit is contained in:
parent
dda5ed696b
commit
94b67603e5
1 changed files with 97 additions and 20 deletions
|
|
@ -189,12 +189,24 @@ struct session {
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
unsigned we_initiated:1;
|
||||||
|
|
||||||
|
#define SESSION_STATE_INIT 0
|
||||||
|
#define SESSION_STATE_SENDING_CTRL_IN 1
|
||||||
|
#define SESSION_STATE_SENDING_DATA_IN 2
|
||||||
|
#define SESSION_STATE_ESTABLISHING 3
|
||||||
|
#define SESSION_STATE_ESTABLISHED 4
|
||||||
|
int state;
|
||||||
|
|
||||||
uint32_t initiator;
|
uint32_t initiator;
|
||||||
uint32_t remote_ssrc;
|
uint32_t remote_ssrc;
|
||||||
|
|
||||||
uint32_t ssrc;
|
uint32_t ssrc;
|
||||||
uint32_t ts_offset;
|
uint32_t ts_offset;
|
||||||
|
|
||||||
|
unsigned sending:1;
|
||||||
|
unsigned receiving:1;
|
||||||
|
|
||||||
unsigned ctrl_ready:1;
|
unsigned ctrl_ready:1;
|
||||||
unsigned data_ready:1;
|
unsigned data_ready:1;
|
||||||
};
|
};
|
||||||
|
|
@ -270,6 +282,7 @@ static void send_apple_midi_cmd_in(struct session *sess, bool ctrl)
|
||||||
struct iovec iov[3];
|
struct iovec iov[3];
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct rtp_apple_midi hdr;
|
struct rtp_apple_midi hdr;
|
||||||
|
int fd;
|
||||||
|
|
||||||
spa_zero(hdr);
|
spa_zero(hdr);
|
||||||
hdr.cmd = htonl(APPLE_MIDI_CMD_IN);
|
hdr.cmd = htonl(APPLE_MIDI_CMD_IN);
|
||||||
|
|
@ -283,12 +296,21 @@ static void send_apple_midi_cmd_in(struct session *sess, bool ctrl)
|
||||||
iov[1].iov_len = strlen(impl->session_name)+1;
|
iov[1].iov_len = strlen(impl->session_name)+1;
|
||||||
|
|
||||||
spa_zero(msg);
|
spa_zero(msg);
|
||||||
msg.msg_name = ctrl ? &sess->ctrl_addr : &sess->data_addr;
|
if (ctrl) {
|
||||||
msg.msg_namelen = ctrl ? sess->ctrl_len : sess->data_len;
|
msg.msg_name = &sess->ctrl_addr;
|
||||||
|
msg.msg_namelen = sess->ctrl_len;
|
||||||
|
fd = impl->ctrl_source->fd;
|
||||||
|
sess->state = SESSION_STATE_SENDING_CTRL_IN;
|
||||||
|
} else {
|
||||||
|
msg.msg_name = &sess->data_addr;
|
||||||
|
msg.msg_namelen = sess->data_len;
|
||||||
|
fd = impl->data_source->fd;
|
||||||
|
sess->state = SESSION_STATE_SENDING_DATA_IN;
|
||||||
|
}
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = 2;
|
msg.msg_iovlen = 2;
|
||||||
|
|
||||||
send_packet(ctrl ? impl->ctrl_source->fd : impl->data_source->fd, &msg);
|
send_packet(fd, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_apple_midi_cmd_by(struct session *sess, bool ctrl)
|
static void send_apple_midi_cmd_by(struct session *sess, bool ctrl)
|
||||||
|
|
@ -316,6 +338,39 @@ static void send_apple_midi_cmd_by(struct session *sess, bool ctrl)
|
||||||
send_packet(ctrl ? impl->ctrl_source->fd : impl->data_source->fd, &msg);
|
send_packet(ctrl ? impl->ctrl_source->fd : impl->data_source->fd, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void session_establish(struct session *sess)
|
||||||
|
{
|
||||||
|
switch (sess->state) {
|
||||||
|
case SESSION_STATE_INIT:
|
||||||
|
/* we initiate */
|
||||||
|
sess->we_initiated = true;
|
||||||
|
if (!sess->ctrl_ready)
|
||||||
|
send_apple_midi_cmd_in(sess, true);
|
||||||
|
else if (!sess->data_ready)
|
||||||
|
send_apple_midi_cmd_in(sess, false);
|
||||||
|
break;
|
||||||
|
case SESSION_STATE_ESTABLISHING:
|
||||||
|
case SESSION_STATE_ESTABLISHED:
|
||||||
|
/* we're done or waiting for other initiator */
|
||||||
|
break;
|
||||||
|
case SESSION_STATE_SENDING_CTRL_IN:
|
||||||
|
case SESSION_STATE_SENDING_DATA_IN:
|
||||||
|
/* we're busy initiating */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void session_stop(struct session *sess)
|
||||||
|
{
|
||||||
|
if (!sess->we_initiated)
|
||||||
|
return;
|
||||||
|
if (sess->ctrl_ready)
|
||||||
|
send_apple_midi_cmd_by(sess, true);
|
||||||
|
if (sess->data_ready)
|
||||||
|
send_apple_midi_cmd_by(sess, false);
|
||||||
|
sess->state = SESSION_STATE_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_destroy(void *data)
|
static void send_destroy(void *data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -327,15 +382,12 @@ static void send_state_changed(void *data, bool started, const char *error)
|
||||||
pw_log_info("send initiator:%08x state %d", sess->initiator, started);
|
pw_log_info("send initiator:%08x state %d", sess->initiator, started);
|
||||||
|
|
||||||
if (started) {
|
if (started) {
|
||||||
if (!sess->ctrl_ready)
|
sess->sending = true;
|
||||||
send_apple_midi_cmd_in(sess, true);
|
session_establish(sess);
|
||||||
else if (!sess->data_ready)
|
|
||||||
send_apple_midi_cmd_in(sess, false);
|
|
||||||
} else {
|
} else {
|
||||||
if (sess->ctrl_ready)
|
sess->sending = false;
|
||||||
send_apple_midi_cmd_by(sess, true);
|
if (!sess->receiving)
|
||||||
if (sess->data_ready)
|
session_stop(sess);
|
||||||
send_apple_midi_cmd_by(sess, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -366,15 +418,12 @@ static void recv_state_changed(void *data, bool started, const char *error)
|
||||||
pw_log_info("send initiator:%08x state %d", sess->initiator, started);
|
pw_log_info("send initiator:%08x state %d", sess->initiator, started);
|
||||||
|
|
||||||
if (started) {
|
if (started) {
|
||||||
if (!sess->ctrl_ready)
|
sess->receiving = true;
|
||||||
send_apple_midi_cmd_in(sess, true);
|
session_establish(sess);
|
||||||
else if (!sess->data_ready)
|
|
||||||
send_apple_midi_cmd_in(sess, false);
|
|
||||||
} else {
|
} else {
|
||||||
if (sess->ctrl_ready)
|
sess->receiving = false;
|
||||||
send_apple_midi_cmd_by(sess, true);
|
if (!sess->sending)
|
||||||
if (sess->data_ready)
|
session_stop(sess);
|
||||||
send_apple_midi_cmd_by(sess, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,6 +599,7 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
||||||
sess->ctrl_addr = *sa;
|
sess->ctrl_addr = *sa;
|
||||||
sess->ctrl_len = salen;
|
sess->ctrl_len = salen;
|
||||||
sess->ctrl_ready = true;
|
sess->ctrl_ready = true;
|
||||||
|
sess->state = SESSION_STATE_ESTABLISHING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -562,6 +612,7 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
||||||
sess->data_addr = *sa;
|
sess->data_addr = *sa;
|
||||||
sess->data_len = salen;
|
sess->data_len = salen;
|
||||||
sess->data_ready = true;
|
sess->data_ready = true;
|
||||||
|
sess->state = SESSION_STATE_ESTABLISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -596,7 +647,7 @@ static void parse_apple_midi_cmd_ok(struct impl *impl, bool ctrl, uint8_t *buffe
|
||||||
struct session *sess;
|
struct session *sess;
|
||||||
|
|
||||||
sess = find_session_by_initiator(impl, initiator);
|
sess = find_session_by_initiator(impl, initiator);
|
||||||
if (sess == NULL) {
|
if (sess == NULL || !sess->we_initiated) {
|
||||||
pw_log_warn("received OK from nonexisting session %u", initiator);
|
pw_log_warn("received OK from nonexisting session %u", initiator);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -610,6 +661,7 @@ static void parse_apple_midi_cmd_ok(struct impl *impl, bool ctrl, uint8_t *buffe
|
||||||
pw_log_info("got data OK %08x", initiator);
|
pw_log_info("got data OK %08x", initiator);
|
||||||
sess->remote_ssrc = ntohl(hdr->ssrc);
|
sess->remote_ssrc = ntohl(hdr->ssrc);
|
||||||
sess->data_ready = true;
|
sess->data_ready = true;
|
||||||
|
sess->state = SESSION_STATE_ESTABLISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -665,6 +717,28 @@ static void parse_apple_midi_cmd_ck(struct impl *impl, bool ctrl, uint8_t *buffe
|
||||||
send_packet(ctrl ? impl->ctrl_source->fd : impl->data_source->fd, &msg);
|
send_packet(ctrl ? impl->ctrl_source->fd : impl->data_source->fd, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_apple_midi_cmd_by(struct impl *impl, bool ctrl, uint8_t *buffer,
|
||||||
|
ssize_t len, struct sockaddr_storage *sa, socklen_t salen)
|
||||||
|
{
|
||||||
|
struct rtp_apple_midi *hdr = (struct rtp_apple_midi*)buffer;
|
||||||
|
uint32_t initiator = ntohl(hdr->initiator);
|
||||||
|
struct session *sess;
|
||||||
|
|
||||||
|
sess = find_session_by_initiator(impl, initiator);
|
||||||
|
if (sess == NULL) {
|
||||||
|
pw_log_warn("received BY from nonexisting initiator %08x", initiator);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl) {
|
||||||
|
pw_log_info("got ctrl BY %08x %d", initiator, sess->data_ready);
|
||||||
|
sess->ctrl_ready = false;
|
||||||
|
} else {
|
||||||
|
pw_log_info("got data BY %08x", initiator);
|
||||||
|
sess->data_ready = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_apple_midi_cmd(struct impl *impl, bool ctrl, uint8_t *buffer,
|
static void parse_apple_midi_cmd(struct impl *impl, bool ctrl, uint8_t *buffer,
|
||||||
ssize_t len, struct sockaddr_storage *sa, socklen_t salen)
|
ssize_t len, struct sockaddr_storage *sa, socklen_t salen)
|
||||||
{
|
{
|
||||||
|
|
@ -679,6 +753,9 @@ static void parse_apple_midi_cmd(struct impl *impl, bool ctrl, uint8_t *buffer,
|
||||||
case APPLE_MIDI_CMD_CK:
|
case APPLE_MIDI_CMD_CK:
|
||||||
parse_apple_midi_cmd_ck(impl, ctrl, buffer, len, sa, salen);
|
parse_apple_midi_cmd_ck(impl, ctrl, buffer, len, sa, salen);
|
||||||
break;
|
break;
|
||||||
|
case APPLE_MIDI_CMD_BY:
|
||||||
|
parse_apple_midi_cmd_by(impl, ctrl, buffer, len, sa, salen);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue