+
+static
+void add_listener(GArray *listeners, void *func, void *data)
+{
+ struct bt_graph_listener listener = {
+ .func = func,
+ .data = data,
+ };
+
+ g_array_append_val(listeners, listener);
+}
+
+enum bt_graph_status bt_graph_add_port_added_listener(
+ struct bt_graph *graph,
+ bt_graph_port_added_listener listener, void *data)
+{
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+ if (!graph || !listener) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ add_listener(graph->listeners.port_added, listener, data);
+
+end:
+ return status;
+}
+
+enum bt_graph_status bt_graph_add_port_removed_listener(
+ struct bt_graph *graph,
+ bt_graph_port_removed_listener listener, void *data)
+{
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+ if (!graph || !listener) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ add_listener(graph->listeners.port_removed, listener, data);
+
+end:
+ return status;
+}
+
+enum bt_graph_status bt_graph_add_port_connected_listener(
+ struct bt_graph *graph,
+ bt_graph_port_connected_listener listener, void *data)
+{
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+ if (!graph || !listener) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ add_listener(graph->listeners.port_connected, listener, data);
+
+end:
+ return status;
+}
+
+enum bt_graph_status bt_graph_add_port_disconnected_listener(
+ struct bt_graph *graph,
+ bt_graph_port_disconnected_listener listener, void *data)
+{
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+ if (!graph || !listener) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ add_listener(graph->listeners.port_disconnected, listener, data);
+
+end:
+ return status;
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
+{
+ size_t i;
+
+ for (i = 0; i < graph->listeners.port_added->len; i++) {
+ struct bt_graph_listener listener =
+ g_array_index(graph->listeners.port_added,
+ struct bt_graph_listener, i);
+ bt_graph_port_added_listener func = listener.func;
+
+ assert(func);
+ func(port, listener.data);
+ }
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_removed(struct bt_graph *graph,
+ struct bt_component *comp, struct bt_port *port)
+{
+ size_t i;
+
+ for (i = 0; i < graph->listeners.port_removed->len; i++) {
+ struct bt_graph_listener listener =
+ g_array_index(graph->listeners.port_removed,
+ struct bt_graph_listener, i);
+ bt_graph_port_removed_listener func = listener.func;
+
+ assert(func);
+ func(comp, port, listener.data);
+ }
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_connected(struct bt_graph *graph,
+ struct bt_port *port)
+{
+ size_t i;
+
+ for (i = 0; i < graph->listeners.port_connected->len; i++) {
+ struct bt_graph_listener listener =
+ g_array_index(graph->listeners.port_connected,
+ struct bt_graph_listener, i);
+ bt_graph_port_connected_listener func = listener.func;
+
+ assert(func);
+ func(port, listener.data);
+ }
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_disconnected(struct bt_graph *graph,
+ struct bt_component *comp, struct bt_port *port)
+{
+ size_t i;
+
+ for (i = 0; i < graph->listeners.port_disconnected->len; i++) {
+ struct bt_graph_listener listener =
+ g_array_index(graph->listeners.port_disconnected,
+ struct bt_graph_listener, i);
+ bt_graph_port_disconnected_listener func = listener.func;
+
+ assert(func);
+ func(comp, port, listener.data);
+ }
+}