Commit f10424e8 authored by Tommy Olofsson's avatar Tommy Olofsson
Browse files

Auto restr. should work now. Yet to be tested.

parent 0633c24c
......@@ -564,6 +564,7 @@ int handle_data_sample_event(void *event_arg)
expected_seqno == fers->data.seqno)
{
size_t size;
int id;
size = fers->data.app_enc_data.n_0;
labcomm_decoder_ioctl(chan->proto_decoder,
......@@ -571,15 +572,44 @@ int handle_data_sample_event(void *event_arg)
fers->data.app_enc_data.a,
size);
labcomm_decoder_decode_one(chan->proto_decoder);
id = labcomm_decoder_decode_one(chan->proto_decoder);
if (fers->data.important) {
chan->remote_seqno = fers->data.seqno;
}
if (id == -ENOENT) {
if (!chan->auto_restrict) {
firefly_error(FIREFLY_ERROR_LABCOMM, 1,
"Unkn. type. Use autorestr.");
} else {
firefly_error(FIREFLY_ERROR_LABCOMM, 1,
"Wait for restr.");
}
} else if (!chan->restricted_local &&
chan->auto_restrict)
{
size_t n = 0;
for (; n < chan->n_decoder_types; n++) {
if (chan->seen_decoder_ids[n] == -1 ||
chan->seen_decoder_ids[n] == id)
{
break;
}
}
chan->seen_decoder_ids[n] = id;
if (n == chan->n_decoder_types-1) {
FIREFLY_FREE(chan->seen_decoder_ids);
chan->seen_decoder_ids = NULL;
channel_auto_restr_send_ack(chan);
}
}
#if 0 /* This would probably be a good idea, but it breaks existing tests. */
} else if (fers->data.important && expected_seqno != fers->data.seqno) {
} else if (fers->data.important &&
expected_seqno != fers->data.seqno)
{
firefly_error(FIREFLY_ERROR_PROTO_STATE, 1,
"Received data flagged important with "
"unexpected sequence number.");
"Received data flagged important with "
"unexpected sequence number.");
#endif
}
} else {
......@@ -800,22 +830,31 @@ int channel_restrict_ack_event(void *context)
FIREFLY_FREE(context);
return -1;
}
if (earg->rack.restricted) {
if (!chan->restricted_remote && chan->restricted_local &&
chan->conn->actions &&
chan->conn->actions->channel_restrict_info) {
conn->actions->channel_restrict_info(chan, RESTRICTED);
} else if (!chan->restricted_local) {
firefly_channel_raise(chan, NULL,
FIREFLY_ERROR_PROTO_STATE, "Inconsistent restrict state.");
}
if (chan->auto_restrict) {
chan->restricted_remote = true;
channel_auto_restr_check_complete(chan);
} else {
enum restriction_transition t;
if (earg->rack.restricted) {
if (!chan->restricted_remote && chan->restricted_local &&
chan->conn->actions &&
chan->conn->actions->channel_restrict_info)
{
conn->actions->channel_restrict_info(chan,
RESTRICTED);
} else if (!chan->restricted_local) {
firefly_channel_raise(chan, NULL,
FIREFLY_ERROR_PROTO_STATE,
"Inconsistent restrict state.");
}
} else {
enum restriction_transition t;
t = chan->restricted_local ? RESTRICTION_DENIED : UNRESTRICTED;
if (conn->actions && conn->actions->channel_restrict_info)
conn->actions->channel_restrict_info(chan, t);
chan->restricted_local = false;
t = chan->restricted_local ?
RESTRICTION_DENIED : UNRESTRICTED;
if (conn->actions && conn->actions->channel_restrict_info)
conn->actions->channel_restrict_info(chan, t);
chan->restricted_local = false;
}
}
chan->restricted_remote = earg->rack.restricted;
firefly_channel_ack(chan);
......@@ -887,6 +926,15 @@ void firefly_channel_set_types(struct firefly_channel *chan,
f->register_func(chan->proto_decoder, f->handler, f->context);
types.decoder_types = f->next;
FIREFLY_FREE(f);
chan->n_decoder_types++;
}
chan->seen_decoder_ids = calloc(chan->n_decoder_types,
sizeof(*chan->seen_decoder_ids));
if (chan->seen_decoder_ids) {
for (size_t i = 0; i < chan->n_decoder_types; i++)
chan->seen_decoder_ids[i] = -1;
} else {
FFL(FIREFLY_ERROR_ALLOC);
}
chan->enc_types = types.encoder_types;
}
......@@ -55,7 +55,10 @@ struct firefly_channel *firefly_channel_new(struct firefly_connection *conn)
chan->conn = conn;
chan->restricted_local = false;
chan->restricted_remote = false;
chan->auto_restrict = false;
chan->enc_types = NULL;
chan->seen_decoder_ids = NULL;
chan->n_decoder_types = 0;
return chan;
}
......@@ -208,9 +211,19 @@ int firefly_channel_unrestrict_event(void *earg)
void firefly_channel_internal_opened(struct firefly_channel *chan)
{
if (chan->state != FIREFLY_CHANNEL_OPEN) {
chan->state = FIREFLY_CHANNEL_OPEN;
chan->conn->actions->channel_opened(chan);
if (chan->state == FIREFLY_CHANNEL_OPEN)
return;
chan->state = FIREFLY_CHANNEL_OPEN;
chan->conn->actions->channel_opened(chan);
if (chan->auto_restrict) {
while (chan->enc_types) {
struct firefly_channel_encoder_type *t;
t = chan->enc_types;
chan->enc_types = t->next;
t->register_func(chan->proto_encoder);
}
}
}
......@@ -271,3 +284,27 @@ void firefly_channel_raise(
if (conn && conn->actions && conn->actions->channel_error)
conn->actions->channel_error(chan, reason, msg);
}
void channel_auto_restr_send_ack(struct firefly_channel *chan)
{
firefly_protocol_channel_restrict_ack resp;
resp.dest_chan_id = chan->remote_id;
resp.source_chan_id = chan->local_id;
resp.restricted = true;
labcomm_encoder_ioctl(chan->conn->transport_encoder,
FIREFLY_LABCOMM_IOCTL_TRANS_SET_IMPORTANT_ID,
&chan->important_id);
labcomm_encode_firefly_protocol_channel_restrict_ack(
chan->conn->transport_encoder,
&resp);
chan->restricted_local = true;
channel_auto_restr_check_complete(chan);
}
void channel_auto_restr_check_complete(struct firefly_channel *chan)
{
if (chan->restricted_local && chan->restricted_remote)
chan->conn->actions->channel_restrict_info(chan, RESTRICTED);
}
......@@ -309,6 +309,8 @@ struct firefly_channel {
bool restricted_remote; /**< Neg. initiated remotely. */
bool auto_restrict;
struct firefly_channel_encoder_type *enc_types;
size_t n_decoder_types;
int *seen_decoder_ids;
};
/**
......@@ -846,4 +848,8 @@ struct firefly_event_chan_open_auto_restrict {
*/
int firefly_channel_open_auto_restrict_event(void *event_arg);
void channel_auto_restr_send_ack(struct firefly_channel *chan);
void channel_auto_restr_check_complete(struct firefly_channel *chan);
#endif
......@@ -202,6 +202,7 @@ void test_chan_recv_accept()
firefly_protocol_channel_request chan_req;
chan_req.source_chan_id = REMOTE_CHAN_ID;
chan_req.dest_chan_id = CHANNEL_ID_NOT_SET;
chan_req.auto_restrict = false;
// Give channel request data to protocol layer.
labcomm_encode_firefly_protocol_channel_request(test_enc, &chan_req);
labcomm_encoder_ioctl(test_enc, LABCOMM_IOCTL_WRITER_GET_BUFFER,
......@@ -268,6 +269,7 @@ void test_chan_recv_reject()
firefly_protocol_channel_request chan_req;
chan_req.dest_chan_id = CHANNEL_ID_NOT_SET;
chan_req.source_chan_id = REMOTE_CHAN_ID;
chan_req.auto_restrict = false;
labcomm_encode_firefly_protocol_channel_request(test_enc, &chan_req);
labcomm_encoder_ioctl(test_enc, LABCOMM_IOCTL_WRITER_GET_BUFFER,
&buf, &buf_size);
......
......@@ -572,6 +572,7 @@ void test_important_handshake_recv()
firefly_protocol_channel_request req_pkt;
req_pkt.source_chan_id = 1;
req_pkt.dest_chan_id = CHANNEL_ID_NOT_SET;
req_pkt.auto_restrict = false;
labcomm_encode_firefly_protocol_channel_request(test_enc, &req_pkt);
labcomm_encoder_ioctl(test_enc, LABCOMM_IOCTL_WRITER_GET_BUFFER,
&buf, &buf_size);
......@@ -629,6 +630,7 @@ void test_important_handshake_recv_errors()
firefly_protocol_channel_request req_pkt;
req_pkt.source_chan_id = 1;
req_pkt.dest_chan_id = CHANNEL_ID_NOT_SET;
req_pkt.auto_restrict = false;
labcomm_encode_firefly_protocol_channel_request(test_enc, &req_pkt);
labcomm_encoder_ioctl(test_enc, LABCOMM_IOCTL_WRITER_GET_BUFFER,
&buf, &buf_size);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment