92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"time"
|
|
|
|
"badat.dev/maeqtt/v2/mqtt/packets"
|
|
)
|
|
|
|
type Connection struct {
|
|
MaxPacketSize *uint32
|
|
RecvMax uint16
|
|
TopicAliasMax uint16
|
|
WantsRespInf bool
|
|
WantsProblemInf bool
|
|
Will packets.Will
|
|
|
|
KeepAliveInterval time.Duration
|
|
keepAliveTicker time.Ticker
|
|
|
|
PacketChannel chan packets.ClientPacket
|
|
ClientDisconnectedChan chan bool
|
|
|
|
rw io.ReadWriteCloser
|
|
}
|
|
|
|
func (c *Connection) resetKeepAlive() {
|
|
if c.KeepAliveInterval != 0 {
|
|
// TODO IMPLEMENT THIS
|
|
//s.keepAliveTicker.Reset(s.KeepAliveInterval)
|
|
}
|
|
}
|
|
|
|
func (c *Connection) readPacket() (*packets.ClientPacket, error) {
|
|
return packets.ReadPacket(bufio.NewReader(c.rw))
|
|
}
|
|
|
|
func (c *Connection) sendPacket(p packets.ServerPacket) error {
|
|
c.resetKeepAlive()
|
|
return p.Write(c.rw)
|
|
}
|
|
|
|
func (c *Connection) close() error {
|
|
close(c.PacketChannel)
|
|
return c.rw.Close()
|
|
}
|
|
|
|
func (c *Connection) packetReadLoop() {
|
|
for {
|
|
pack, err := c.readPacket()
|
|
if err == io.EOF {
|
|
c.ClientDisconnectedChan <- true
|
|
} else if err != nil {
|
|
panic(fmt.Errorf("Unimplemented error handling, %e", err).Error())
|
|
} else {
|
|
c.PacketChannel <- *pack
|
|
}
|
|
}
|
|
}
|
|
|
|
func NewConnection(p packets.ConnectPacket, rw io.ReadWriteCloser) Connection {
|
|
conn := Connection{}
|
|
conn.rw = rw
|
|
|
|
if p.Properties.ReceiveMaximum.Value != nil {
|
|
conn.RecvMax = *p.Properties.ReceiveMaximum.Value
|
|
} else {
|
|
conn.RecvMax = 65535
|
|
}
|
|
conn.MaxPacketSize = p.Properties.MaximumPacketSize.Value
|
|
|
|
if p.Properties.TopicAliasMaximum.Value != nil {
|
|
conn.TopicAliasMax = *p.Properties.TopicAliasMaximum.Value
|
|
} else {
|
|
conn.TopicAliasMax = 0
|
|
}
|
|
|
|
if p.Properties.RequestProblemInformation.Value != nil {
|
|
conn.WantsRespInf = *p.Properties.RequestProblemInformation.Value != 0
|
|
} else {
|
|
conn.WantsRespInf = false
|
|
}
|
|
|
|
conn.KeepAliveInterval = time.Duration(p.KeepAliveInterval) * time.Second
|
|
|
|
conn.PacketChannel = make(chan packets.ClientPacket)
|
|
|
|
go conn.packetReadLoop()
|
|
return conn
|
|
}
|