actioncam/libipcamera/protocol.go
2019-08-29 10:24:02 +02:00

76 lines
1.9 KiB
Go

package libipcamera
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/icza/bitio"
)
// Header is an ipcamera protocol message header
type Header struct {
Magic uint16
Length uint16
MessageType uint32
}
func (h *Header) String() string {
return fmt.Sprintf("{ Header Magic=0x%X, Length=%d, MessageType=0x%X }", h.Magic, h.Length, h.MessageType)
}
// Message represents a complete message from/to the camera
type Message struct {
Header Header
Payload []byte
}
func (m *Message) String() string {
return fmt.Sprintf("{ Message\n\tHeader=%s,\n\tPayload=\n%s\n}", m.Header.String(), hex.Dump(m.Payload))
}
// StreamHeader is a live preview message header
type StreamHeader struct {
Magic uint16
Length uint16
SequenceNumber uint16
MessageType uint16
}
// CreatePacket creates a packet ready to be sent to the camera
func CreatePacket(header Header, payload []byte) []byte {
header.Length = (uint16)(len(payload))
buf := &bytes.Buffer{}
w := bitio.NewWriter(buf)
w.WriteBits((uint64)(header.Magic), 16)
w.WriteBits((uint64)(header.Length), 16)
w.WriteBits((uint64)(header.MessageType), 32)
w.Write(payload)
return buf.Bytes()
}
// CreateCommandHeader prepares a packet header for command packets
func CreateCommandHeader(command uint32) Header {
return Header{
Magic: 0xABCD,
Length: 0,
MessageType: command,
}
}
// CreateLoginPacket creates a Login packet to be sent to the camera
func CreateLoginPacket(username, password string) []byte {
header := CreateCommandHeader(0x00000110) // Login
payload := make([]byte, 128)
copy(payload, []byte(username))
copy(payload[64:], []byte(password))
return CreatePacket(header, payload)
}
// CreateCommandPacket prepares a command packet to be sent to the camera
func CreateCommandPacket(command uint32) []byte {
header := CreateCommandHeader(command)
return CreatePacket(header, []byte{})
}