wip
This commit is contained in:
commit
af3aa637d2
|
@ -0,0 +1,12 @@
|
||||||
|
package tplink
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscoveryOptions struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) StartDiscovery(do *DiscoveryOptions) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package codec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const DefaultFirstByte = 0xab
|
||||||
|
|
||||||
|
type XorEncoder struct {
|
||||||
|
wr io.Writer
|
||||||
|
wb *bufio.Writer
|
||||||
|
last byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XorEncoder) Write(p []byte) (n int, err error) {
|
||||||
|
var next byte
|
||||||
|
for _, v := range p {
|
||||||
|
next = v ^ x.last
|
||||||
|
x.last = next
|
||||||
|
err = x.wb.WriteByte(next)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n = n + 1
|
||||||
|
}
|
||||||
|
err = x.wb.Flush()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewXorEncoder(wr io.Writer, first byte) *XorEncoder {
|
||||||
|
return &XorEncoder{
|
||||||
|
wr: wr,
|
||||||
|
wb: bufio.NewWriter(wr),
|
||||||
|
last: first,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type XorDecoder struct {
|
||||||
|
rd io.Reader
|
||||||
|
last byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XorDecoder) Read(p []byte) (n int, err error) {
|
||||||
|
n, err = x.rd.Read(p)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
var next byte
|
||||||
|
for idx := 0; idx < n; idx++ {
|
||||||
|
next = p[idx]
|
||||||
|
p[idx] ^= x.last
|
||||||
|
x.last = next
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewXorDecoder(rd io.Reader, first byte) *XorDecoder {
|
||||||
|
return &XorDecoder{
|
||||||
|
rd: rd,
|
||||||
|
last: first,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package codec_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"tuxpa.in/a/tplink/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
plain string
|
||||||
|
encryptedBuf []byte
|
||||||
|
encryptedBufWithHeader []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustDecode64(xs string) []byte {
|
||||||
|
val, err := base64.StdEncoding.DecodeString(xs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCases = map[string]testCase{
|
||||||
|
"setPowerStateOn": {
|
||||||
|
plain: `{"system":{"set_relay_state":{"state":1}}}`,
|
||||||
|
encryptedBuf: mustDecode64(`0PKB+Iv/mvfV75S2xaDUi/mc8JHot8Sw0aXA4tijgfKG55P21O7fot+i`),
|
||||||
|
encryptedBufWithHeader: mustDecode64(`AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu36Lfog==`),
|
||||||
|
},
|
||||||
|
"setPowerStateOff": {
|
||||||
|
plain: `{"system":{"set_relay_state":{"state":0}}}`,
|
||||||
|
encryptedBuf: mustDecode64(`0PKB+Iv/mvfV75S2xaDUi/mc8JHot8Sw0aXA4tijgfKG55P21O7eo96j`),
|
||||||
|
encryptedBufWithHeader: mustDecode64(`AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu3qPeow==`),
|
||||||
|
},
|
||||||
|
"getSysInfo": {
|
||||||
|
plain: `{ "system":{ "get_sysinfo":null } }`,
|
||||||
|
encryptedBuf: mustDecode64(`0PDSodir37rX9c+0lLbRtMCf7JXmj+GH6MrwnuuH68u2lus=`),
|
||||||
|
encryptedBufWithHeader: mustDecode64(`AAAAI9Dw0qHYq9+61/XPtJS20bTAn+yV5o/hh+jK8J7rh+vLtpbr`),
|
||||||
|
},
|
||||||
|
"getConsumption": {
|
||||||
|
plain: `{ "emeter":{ "get_realtime":null } }`,
|
||||||
|
encryptedBuf: mustDecode64(`0PDSt9q/y67c/sS/n73av8uU5oPijvqT/pu5g+2Y9Ji4xeWY`),
|
||||||
|
encryptedBufWithHeader: mustDecode64(`AAAAJNDw0rfav8uu3P7Ev5+92r/LlOaD4o76k/6buYPtmPSYuMXlmA==`),
|
||||||
|
},
|
||||||
|
"specialChars": {
|
||||||
|
plain: `right single quotation mark:’ left double quotation mark:“ right double quotation mark:” kissing cat face with closed eyes:😽`,
|
||||||
|
encryptedBuf: mustDecode64(`2bDXv8vrmPGf+JTx0aDVus6v27Lds5P+n+2GvF7eR2cLbgh8XDhXIkAsSWkYbQJ2F2MKZQsrRidVPgTmZvraqMGmzrqa/pHkhuqPr96rxLDRpcyjze2A4ZP4wiCgPR12H2wfdhh/XzxdKQlvDm0IKF82QioKaQVqGXwYOF0kQTII+Gf/Qg==`),
|
||||||
|
encryptedBufWithHeader: mustDecode64(`AAAAhdmw17/L65jxn/iU8dGg1brOr9uy3bOT/p/thrxe3kdnC24IfFw4VyJALElpGG0CdhdjCmULK0YnVT4E5mb62qjBps66mv6R5Ibqj6/eq8Sw0aXMo83tgOGT+MIgoD0ddh9sH3YYf188XSkJbw5tCChfNkIqCmkFahl8GDhdJEEyCPhn/0I=`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncoder(t *testing.T) {
|
||||||
|
for k, v := range testCases {
|
||||||
|
t.Run(k, func(t *testing.T) {
|
||||||
|
ans := new(bytes.Buffer)
|
||||||
|
enc := codec.NewXorEncoder(ans, codec.DefaultFirstByte)
|
||||||
|
_, err := enc.Write([]byte(v.plain))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, v.encryptedBuf, ans.Bytes())
|
||||||
|
lenb := binary.BigEndian.AppendUint32(nil, uint32(ans.Len()))
|
||||||
|
assert.EqualValues(t, v.encryptedBufWithHeader, append(lenb, ans.Bytes()...))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestDecoder(t *testing.T) {
|
||||||
|
for k, v := range testCases {
|
||||||
|
t.Run(k, func(t *testing.T) {
|
||||||
|
enc := codec.NewXorDecoder(bytes.NewBuffer(v.encryptedBuf), codec.DefaultFirstByte)
|
||||||
|
pkt, err := io.ReadAll(enc)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, v.plain, string(pkt))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
module tuxpa.in/a/tplink
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.8.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,17 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
Loading…
Reference in New Issue