aboutsummaryrefslogtreecommitdiff
path: root/inform/inform.go
blob: 5c3ca1cb1a3554811bfdd2794ecc6666c63d1590 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package inform

import (
	"bytes"
	"encoding/json"
	"fmt"
)

const (
	PROTOCOL_MAGIC int32 = 1414414933 // UBNT
	INFORM_VERSION int32 = 0
	DATA_VERSION   int32 = 1

	ENCRYPTED_FLAG  = 1
	COMPRESSED_FLAG = 2
)

// Wrapper around an inform message, serializes directly into the wire
// protocol
type InformWrapper struct {
	Version     int32
	MacAddr     []byte
	Flags       int16
	DataVersion int32
	Payload     []byte
}

// Create InformWrapper with sane defaults
func NewInformWrapper() *InformWrapper {
	return &InformWrapper{
		Version:     INFORM_VERSION,
		MacAddr:     make([]byte, 6),
		Flags:       0,
		DataVersion: DATA_VERSION,
	}
}

// Update the payload data with JSON value
func (i *InformWrapper) UpdatePayload(v interface{}) error {
	if d, err := json.Marshal(v); err != nil {
		return err
	} else {
		i.Payload = d
		return nil
	}
}

// Format Mac address bytes as lowercase string with colons
func (i *InformWrapper) FormattedMac() string {
	return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
		i.MacAddr[0], i.MacAddr[1], i.MacAddr[2],
		i.MacAddr[3], i.MacAddr[4], i.MacAddr[5])
}

func (i *InformWrapper) String() string {
	b := &bytes.Buffer{}

	fmt.Fprintf(b, "Version:      \t%d\n", i.Version)
	fmt.Fprintf(b, "Mac Addr:     \t%s\n", i.FormattedMac())
	fmt.Fprintf(b, "Flags:        \t%d\n", i.Flags)
	fmt.Fprintf(b, " Encrypted:   \t%t\n", i.IsEncrypted())
	fmt.Fprintf(b, " Compressed:  \t%t\n", i.IsCompressed())
	fmt.Fprintf(b, "Data Version: \t%d\n", i.DataVersion)
	fmt.Fprintf(b, "Payload:      \t%q\n", i.Payload)

	return b.String()
}

func (i *InformWrapper) IsEncrypted() bool {
	return i.Flags&ENCRYPTED_FLAG != 0
}

func (i *InformWrapper) SetEncrypted(e bool) {
	if e {
		i.Flags |= ENCRYPTED_FLAG
	} else {
		i.Flags &= ENCRYPTED_FLAG
	}
}

func (i *InformWrapper) IsCompressed() bool {
	return i.Flags&COMPRESSED_FLAG != 0
}

func (i *InformWrapper) SetCompressed(c bool) {
	if c {
		i.Flags |= COMPRESSED_FLAG
	} else {
		i.Flags &= COMPRESSED_FLAG
	}
}