@@ -362,7 +362,8 @@ struct snd_seq_client_info {
int card; /* RO: card number[kernel] */
int pid; /* RO: pid[user] */
unsigned int midi_version; /* MIDI version */
- char reserved[52]; /* for future use */
+ unsigned int group_filter; /* UMP group filter bitmap (for 1-based Group indices) */
+ char reserved[48]; /* for future use */
};
/* MIDI version numbers in client info */
@@ -1229,6 +1229,7 @@ static void get_client_info(struct snd_seq_client *cptr,
info->filter = cptr->filter;
info->event_lost = cptr->event_lost;
memcpy(info->event_filter, cptr->event_filter, 32);
+ info->group_filter = cptr->group_filter;
info->num_ports = cptr->num_ports;
if (cptr->type == USER_CLIENT)
@@ -1290,6 +1291,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3))
client->midi_version = client_info->midi_version;
memcpy(client->event_filter, client_info->event_filter, 32);
+ client->group_filter = client_info->group_filter;
return 0;
}
@@ -40,6 +40,7 @@ struct snd_seq_client {
int number; /* client number */
unsigned int filter; /* filter flags */
DECLARE_BITMAP(event_filter, 256);
+ unsigned short group_filter;
snd_use_lock_t use_lock;
int event_lost;
/* ports */
@@ -527,6 +527,17 @@ static int deliver_with_group_convert(struct snd_seq_client *dest,
atomic, hop);
}
+/* apply the UMP event filter; return true to skip the event */
+static bool ump_event_filtered(struct snd_seq_client *dest,
+ const struct snd_seq_ump_event *ev)
+{
+ unsigned char group;
+
+ group = ump_message_group(ev->ump[0]);
+ /* check the bitmap for 1-based group number */
+ return dest->group_filter & (1U << (group + 1));
+}
+
/* Convert from UMP packet and deliver */
int snd_seq_deliver_from_ump(struct snd_seq_client *source,
struct snd_seq_client *dest,
@@ -539,6 +550,8 @@ int snd_seq_deliver_from_ump(struct snd_seq_client *source,
if (snd_seq_ev_is_variable(event))
return 0; // skip, no variable event for UMP, so far
+ if (ump_event_filtered(dest, ump_ev))
+ return 0; // skip if group filter is set and matching
type = ump_message_type(ump_ev->ump[0]);
if (snd_seq_client_is_ump(dest)) {