pnyx/channel.go

139 lines
3.9 KiB
Go

package pnyx
import (
"fmt"
"github.com/google/uuid"
)
2024-04-12 18:06:57 -06:00
type ChannelID byte
const (
MODE_RAW ModeID = iota
2024-04-12 18:06:57 -06:00
MODE_AUDIO
2024-04-12 18:06:57 -06:00
AUDIO_SET_SAMPLE_RATE = iota
AUDIO_GET_SAMPLE_RATE
)
type ModeID uint8
type CommandID uint8
type Permission string
type Channel struct {
id ChannelID
2024-04-11 21:05:50 -06:00
name string
modes map[ModeID]Mode
members []*ServerSession
}
func(channel *Channel) Data(session *ServerSession, mode ModeID, data []byte) {
m, has_mode := channel.modes[mode]
if has_mode {
m.Data(session, channel.id, channel.members, data)
}
}
func(channel *Channel) Command(session *ServerSession, command byte, request_id uuid.UUID, mode_id ModeID, data []byte) error {
mode, has_mode := channel.modes[mode_id]
if has_mode == false {
return fmt.Errorf("Channel has no mode 0x%02x", mode)
} else {
return mode.Command(session, command, request_id, channel.id, channel.members, data)
}
}
func(channel *Channel) Join(client PeerID, session SessionID) {
}
func(channel *Channel) Leave(client PeerID, session SessionID) {
}
type Mode interface {
Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) error
Data(session *ServerSession, channel_id ChannelID, members []*ServerSession, data []byte)
Join(client PeerID, session SessionID)
Leave(client PeerID, session SessionID)
}
func multiplex_without_sender(origin SessionID, packet *Packet, sessions []*ServerSession) {
for _, session := range(sessions) {
if session.ID == origin {
continue
}
session.OutgoingPackets <- packet
2024-04-12 18:06:57 -06:00
}
}
func multiplex(packet *Packet, sessions []*ServerSession) {
for _, session := range(sessions) {
session.OutgoingPackets <- packet
}
}
type RawMode struct {
}
func(mode *RawMode) Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) error {
return fmt.Errorf("unknown raw mode command 0x%02x", command)
}
2024-04-08 17:23:55 -06:00
func(mode *RawMode) Data(session *ServerSession, channel_id ChannelID, members []*ServerSession, data []byte) {
new_packet := NewChannelPeerPacket(session.Peer, channel_id, MODE_RAW, data)
multiplex_without_sender(session.ID, new_packet, members)
}
func(mode *RawMode) Join(client PeerID, session SessionID) {
}
func(mode *RawMode) Leave(client PeerID, session SessionID) {
2024-04-12 18:06:57 -06:00
}
type SampleRate byte
const (
SAMPLE_RATE_UNSET SampleRate = 0xFF
SAMPLE_RATE_24KHZ = 0x01
SAMPLE_RATE_48KHZ = 0x02
)
type AudioMode struct {
SampleRate SampleRate
}
func(mode *AudioMode) Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) error {
switch command {
2024-04-12 18:06:57 -06:00
case AUDIO_SET_SAMPLE_RATE:
if len(data) == 1 {
switch SampleRate(data[0]) {
2024-04-12 18:06:57 -06:00
case SAMPLE_RATE_24KHZ:
fallthrough
case SAMPLE_RATE_48KHZ:
mode.SampleRate = SampleRate(data[0])
update_packet := NewChannelCommandPacket(request_id, channel_id, MODE_AUDIO, AUDIO_SET_SAMPLE_RATE, data)
multiplex(update_packet, members)
return nil
2024-04-12 18:06:57 -06:00
default:
return fmt.Errorf("Invalid sample rate: %x", data[0])
2024-04-12 18:06:57 -06:00
}
} else {
return fmt.Errorf("Invalid AUDIO_SET_SAMPLE_RATE payload: %x", data)
2024-04-12 18:06:57 -06:00
}
case AUDIO_GET_SAMPLE_RATE:
session.OutgoingPackets <- NewChannelCommandPacket(request_id, channel_id, MODE_AUDIO, AUDIO_SET_SAMPLE_RATE, []byte{byte(mode.SampleRate)})
return nil
2024-04-12 18:06:57 -06:00
default:
return fmt.Errorf("unknown audio mode command 0x%02x", command)
2024-04-12 18:06:57 -06:00
}
}
func(mode *AudioMode) Data(session *ServerSession, channel_id ChannelID, members []*ServerSession, data []byte) {
new_packet := NewChannelPeerPacket(session.Peer, channel_id, MODE_AUDIO, data)
multiplex_without_sender(session.ID, new_packet, members)
}
func(mode *AudioMode) Join(client PeerID, session SessionID) {
}
func(mode *AudioMode) Leave(client PeerID, session SessionID) {
}