+static
+GString *message_types_to_string(guint msg_types)
+{
+ GString *str = g_string_new("");
+
+ for (int msg_type = 1; msg_type <= BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY;
+ msg_type <<= 1) {
+ if (msg_type & msg_types) {
+ if (str->len > 0) {
+ g_string_append_c(str, '|');
+ }
+
+ g_string_append(str,
+ bt_common_message_type_string(msg_type));
+ }
+ }
+
+ return str;
+}
+
+static
+void update_expected_msg_type(const struct bt_stream *stream,
+ struct per_stream_state *state,
+ const struct bt_message *msg)
+{
+ switch (msg->type) {
+ case BT_MESSAGE_TYPE_STREAM_BEGINNING:
+ state->expected_msg_types = BT_MESSAGE_TYPE_STREAM_END;
+
+ if (stream->class->supports_packets) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_PACKET_BEGINNING;
+
+ if (stream->class->supports_discarded_packets) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_PACKETS;
+ }
+ } else {
+ state->expected_msg_types |= BT_MESSAGE_TYPE_EVENT;
+ }
+
+ if (stream->class->supports_discarded_events) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+ }
+
+ break;
+ case BT_MESSAGE_TYPE_STREAM_END:
+ state->expected_msg_types = 0;
+ break;
+ case BT_MESSAGE_TYPE_EVENT:
+ {
+ state->expected_msg_types = BT_MESSAGE_TYPE_EVENT;
+
+ if (stream->class->supports_packets) {
+ state->expected_msg_types |= BT_MESSAGE_TYPE_PACKET_END;
+ } else {
+ state->expected_msg_types |= BT_MESSAGE_TYPE_STREAM_END;
+ }
+
+ if (stream->class->supports_discarded_events) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+ }
+
+ break;
+ }
+ case BT_MESSAGE_TYPE_PACKET_BEGINNING:
+ {
+ state->expected_msg_types = BT_MESSAGE_TYPE_EVENT |
+ BT_MESSAGE_TYPE_PACKET_END;
+
+ if (stream->class->supports_discarded_events) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+ }
+
+ break;
+ }
+ case BT_MESSAGE_TYPE_PACKET_END:
+ {
+ state->expected_msg_types = BT_MESSAGE_TYPE_PACKET_BEGINNING |
+ BT_MESSAGE_TYPE_STREAM_END;
+
+ if (stream->class->supports_discarded_events) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+ }
+
+ if (stream->class->supports_discarded_packets) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_PACKETS;
+ }
+
+ break;
+ }
+ case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
+ state->expected_msg_types = BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+
+ if (state->cur_packet) {
+ state->expected_msg_types |= BT_MESSAGE_TYPE_EVENT |
+ BT_MESSAGE_TYPE_PACKET_END;
+ } else {
+ state->expected_msg_types |= BT_MESSAGE_TYPE_STREAM_END;
+
+ if (stream->class->supports_packets) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_PACKET_BEGINNING;
+
+ if (stream->class->supports_discarded_packets) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_PACKETS;
+ }
+ } else {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_EVENT;
+ }
+ }
+
+ break;
+ case BT_MESSAGE_TYPE_DISCARDED_PACKETS:
+ state->expected_msg_types = BT_MESSAGE_TYPE_DISCARDED_PACKETS |
+ BT_MESSAGE_TYPE_PACKET_BEGINNING |
+ BT_MESSAGE_TYPE_STREAM_END;
+
+ if (stream->class->supports_discarded_events) {
+ state->expected_msg_types |=
+ BT_MESSAGE_TYPE_DISCARDED_EVENTS;
+ }
+ break;
+ default:
+ /*
+ * Other message types are not associated to a stream, so we
+ * should not get them here.
+ */
+ bt_common_abort();
+ }
+}
+