Skip to content

Commit 4a1eec6

Browse files
committed
fix: validate port direction before attempting ALSA MIDI connections
1 parent f81ff82 commit 4a1eec6

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

alsa.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,14 @@ def debug_port_capabilities(port_str: str) -> str:
311311
return "cannot get port info"
312312

313313
caps = alsalib.snd_seq_port_info_get_capability(pinfo_ptr)
314-
alsalib.snd_seq_port_info_free(pinfo_ptr)
315-
314+
315+
# Get port direction - need to define the constants
316+
SND_SEQ_PORT_DIR_INPUT = 1
317+
SND_SEQ_PORT_DIR_OUTPUT = 2
318+
319+
# Check if we can get direction from the port info structure
320+
# Note: This is a simplified approach since we don't have direct access to direction
321+
316322
cap_strings = []
317323
if caps & SND_SEQ_PORT_CAP_READ:
318324
cap_strings.append("READ")
@@ -322,7 +328,14 @@ def debug_port_capabilities(port_str: str) -> str:
322328
cap_strings.append("SUBS_WRITE")
323329
if caps & (1 << 4): # SND_SEQ_PORT_CAP_SUBS_READ
324330
cap_strings.append("SUBS_READ")
331+
332+
# Determine port type based on capabilities
333+
if caps & SND_SEQ_PORT_CAP_READ and caps & SND_SEQ_PORT_CAP_SUBS_READ:
334+
cap_strings.append("OUTPUT")
335+
if caps & SND_SEQ_PORT_CAP_WRITE and caps & SND_SEQ_PORT_CAP_SUBS_WRITE:
336+
cap_strings.append("INPUT")
325337

338+
alsalib.snd_seq_port_info_free(pinfo_ptr)
326339
return f"caps=0x{caps:x} [{', '.join(cap_strings)}]"
327340

328341

@@ -358,6 +371,36 @@ def connect_alsa_ports(source_str: str, dest_str: str) -> bool:
358371
)
359372
return False
360373

374+
# Check port capabilities - source must be readable, dest must be writable
375+
pinfo_ptr = snd_seq_port_info_t()
376+
alsalib.snd_seq_port_info_malloc(ctypes.byref(pinfo_ptr))
377+
378+
# Check source capabilities
379+
if alsalib.snd_seq_get_any_port_info(seq, sender.client, sender.port, pinfo_ptr) < 0:
380+
alsalib.snd_seq_port_info_free(pinfo_ptr)
381+
print(f" [ERROR] Cannot get source port info")
382+
return False
383+
384+
source_caps = alsalib.snd_seq_port_info_get_capability(pinfo_ptr)
385+
if not (source_caps & SND_SEQ_PORT_CAP_READ):
386+
alsalib.snd_seq_port_info_free(pinfo_ptr)
387+
print(f" [ERROR] Source port is not readable (cannot send data)")
388+
return False
389+
390+
# Check destination capabilities
391+
if alsalib.snd_seq_get_any_port_info(seq, dest.client, dest.port, pinfo_ptr) < 0:
392+
alsalib.snd_seq_port_info_free(pinfo_ptr)
393+
print(f" [ERROR] Cannot get destination port info")
394+
return False
395+
396+
dest_caps = alsalib.snd_seq_port_info_get_capability(pinfo_ptr)
397+
if not (dest_caps & SND_SEQ_PORT_CAP_WRITE):
398+
alsalib.snd_seq_port_info_free(pinfo_ptr)
399+
print(f" [ERROR] Destination port is not writable (cannot receive data)")
400+
return False
401+
402+
alsalib.snd_seq_port_info_free(pinfo_ptr)
403+
361404
# Check if connection already exists
362405
query_ptr = snd_seq_query_subscribe_t()
363406
alsalib.snd_seq_query_subscribe_malloc(ctypes.byref(query_ptr))

0 commit comments

Comments
 (0)