110 lines
2.5 KiB
Go
110 lines
2.5 KiB
Go
package session
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"io"
|
|
"log"
|
|
"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 != nil {
|
|
c.ClientDisconnectedChan <- true
|
|
c.close()
|
|
} else {
|
|
c.PacketChannel <- *pack
|
|
}
|
|
}
|
|
}
|
|
|
|
var FirstPackNotConnect error = errors.New("Failed to connect, first packet is not connect")
|
|
|
|
func NewConnection(rw io.ReadWriteCloser) (ConnectionRequest, error) {
|
|
connReq := ConnectionRequest{}
|
|
|
|
conn := Connection{}
|
|
connReq.Connection = &conn
|
|
|
|
conn.rw = rw
|
|
packet, err := conn.readPacket()
|
|
conPack, isConn := (*packet).(packets.ConnectPacket)
|
|
if !isConn {
|
|
log.Println("Didn't recieve a connect packet")
|
|
err := packets.DisconnectPacket{
|
|
ReasonCode: packets.DisconnectReasonCodeProtocolError,
|
|
}.Write(rw)
|
|
if err != nil {
|
|
log.Println("Failed to disconnect after not recieving a connect packet", err)
|
|
}
|
|
return connReq, FirstPackNotConnect
|
|
}
|
|
connReq.ConnectPakcet = conPack
|
|
|
|
if conPack.Properties.ReceiveMaximum.Value != nil {
|
|
conn.RecvMax = *conPack.Properties.ReceiveMaximum.Value
|
|
} else {
|
|
conn.RecvMax = 65535
|
|
}
|
|
conn.MaxPacketSize = conPack.Properties.MaximumPacketSize.Value
|
|
|
|
if conPack.Properties.TopicAliasMaximum.Value != nil {
|
|
conn.TopicAliasMax = *conPack.Properties.TopicAliasMaximum.Value
|
|
} else {
|
|
conn.TopicAliasMax = 0
|
|
}
|
|
|
|
if conPack.Properties.RequestProblemInformation.Value != nil {
|
|
conn.WantsRespInf = *conPack.Properties.RequestProblemInformation.Value != 0
|
|
} else {
|
|
conn.WantsRespInf = false
|
|
}
|
|
|
|
conn.KeepAliveInterval = time.Duration(conPack.KeepAliveInterval) * time.Second
|
|
|
|
conn.PacketChannel = make(chan packets.ClientPacket, 1)
|
|
|
|
return connReq, err
|
|
}
|