+static
+enum bt_notification_iterator_status muxer_upstream_notif_iter_next(
+ struct muxer_upstream_notif_iter *muxer_upstream_notif_iter)
+{
+ enum bt_notification_iterator_status status;
+
+ status = bt_notification_iterator_next(
+ muxer_upstream_notif_iter->notif_iter);
+
+ switch (status) {
+ case BT_NOTIFICATION_ITERATOR_STATUS_OK:
+ /*
+ * Notification iterator's current notification is valid:
+ * it must be considered for muxing operations.
+ */
+ muxer_upstream_notif_iter->is_valid = true;
+ break;
+ case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN:
+ /*
+ * Notification iterator's current notification is not
+ * valid anymore. Return
+ * BT_NOTIFICATION_ITERATOR_STATUS_AGAIN
+ * immediately.
+ */
+ muxer_upstream_notif_iter->is_valid = false;
+ break;
+ case BT_NOTIFICATION_ITERATOR_STATUS_END: /* Fall-through. */
+ case BT_NOTIFICATION_ITERATOR_STATUS_CANCELED:
+ /*
+ * Notification iterator reached the end: release it. It
+ * won't be considered again to find the youngest
+ * notification.
+ */
+ BT_PUT(muxer_upstream_notif_iter->notif_iter);
+ muxer_upstream_notif_iter->is_valid = false;
+ status = BT_NOTIFICATION_ITERATOR_STATUS_OK;
+ break;
+ default:
+ /* Error or unsupported status code */
+ status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+ break;
+ }
+
+ return status;
+}
+
+static
+int muxer_notif_iter_handle_newly_connected_ports(
+ struct muxer_notif_iter *muxer_notif_iter)
+{
+ int ret = 0;
+
+ /*
+ * Here we create one upstream notification iterator for each
+ * newly connected port. We do not perform an initial "next" on
+ * those new upstream notification iterators: they are
+ * invalidated, to be validated later. The list of newly
+ * connected ports to handle here is updated by
+ * muxer_port_connected().
+ */
+ while (true) {
+ GList *node = muxer_notif_iter->newly_connected_priv_ports;
+ struct bt_private_port *priv_port;
+ struct bt_port *port;
+ struct bt_notification_iterator *upstream_notif_iter = NULL;
+ struct muxer_upstream_notif_iter *muxer_upstream_notif_iter;
+
+ if (!node) {
+ break;
+ }
+
+ priv_port = node->data;
+ port = bt_port_from_private_port(priv_port);
+ assert(port);
+
+ if (!bt_port_is_connected(port)) {
+ /*
+ * Looks like this port is not connected
+ * anymore: we can't create an upstream
+ * notification iterator on its (non-existing)
+ * connection in this case.
+ */
+ goto remove_node;
+ }
+
+ BT_PUT(port);
+ upstream_notif_iter = create_notif_iter_on_input_port(priv_port,
+ &ret);
+ if (ret) {
+ assert(!upstream_notif_iter);
+ goto error;
+ }
+
+ muxer_upstream_notif_iter =
+ muxer_notif_iter_add_upstream_notif_iter(
+ muxer_notif_iter, upstream_notif_iter,
+ priv_port);
+ BT_PUT(upstream_notif_iter);
+ if (!muxer_upstream_notif_iter) {
+ goto error;
+ }
+
+remove_node:
+ bt_put(upstream_notif_iter);
+ bt_put(port);
+ muxer_notif_iter->newly_connected_priv_ports =
+ g_list_delete_link(
+ muxer_notif_iter->newly_connected_priv_ports,
+ node);
+ }
+
+ goto end;
+
+error:
+ if (ret >= 0) {
+ ret = -1;
+ }
+
+end:
+ return ret;
+}
+