diff --git a/protocol/packet/discovery.go b/protocol/packet/discovery.go new file mode 100644 index 0000000..455fed8 --- /dev/null +++ b/protocol/packet/discovery.go @@ -0,0 +1,16 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet + +func NewDiscovery() { + +} diff --git a/protocol/packet/identity.go b/protocol/packet/identity.go new file mode 100644 index 0000000..2ad597f --- /dev/null +++ b/protocol/packet/identity.go @@ -0,0 +1,38 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet + +import ( + "encoding/json" + "fmt" +) + +type Identity struct { + DeviceId string + DeviceName string + DeviceType string + ProtocolVersion uint + IncomingCapabilities []string + OutgoingCapabilities []string + TcpPort uint +} + +func (p *Packet) AsIdentity() (*Identity, error) { + if p.Type != "kdeconnect.identity" { + return nil, fmt.Errorf("not an identity packet, unexpected type %q", p.Type) + } + var identity Identity + if err := json.Unmarshal(p.Body, &identity); err != nil { + return nil, err + } + return &identity, nil +} diff --git a/protocol/packet/identity_test.go b/protocol/packet/identity_test.go new file mode 100644 index 0000000..f5eac47 --- /dev/null +++ b/protocol/packet/identity_test.go @@ -0,0 +1,39 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/bboozzoo/mconnect/protocol/packet" +) + +func TestPacketAsIdentity(t *testing.T) { + p := packet.Packet{ + Type: "kdeconnect.ping", + Body: json.RawMessage(`foo`), + } + i, err := p.AsIdentity() + assert.Nil(t, i) + assert.Error(t, err) + + p = packet.Packet{ + Type: "kdeconnect.identity", + Body: json.RawMessage(`{}`), + } + i, err = p.AsIdentity() + assert.NotNil(t, i) + assert.NoError(t, err) +} diff --git a/protocol/packet/packet.go b/protocol/packet/packet.go new file mode 100644 index 0000000..579d145 --- /dev/null +++ b/protocol/packet/packet.go @@ -0,0 +1,22 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet + +import ( + "encoding/json" +) + +type Packet struct { + Id uint64 + Type string + Body json.RawMessage +} diff --git a/protocol/packet/parser.go b/protocol/packet/parser.go new file mode 100644 index 0000000..775b0fe --- /dev/null +++ b/protocol/packet/parser.go @@ -0,0 +1,34 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet + +import ( + "bytes" + "encoding/json" + "fmt" +) + +func FromData(data []byte) (*Packet, error) { + var p Packet + + if idx := bytes.LastIndexByte(data, '\n'); idx != -1 { + data = data[0:idx] + } + if err := json.Unmarshal(data, &p); err != nil { + return nil, err + } + + if p.Id == uint64(0) || p.Type == "" || p.Body == nil { + return nil, fmt.Errorf("packet incomplete, missing id, type or body") + } + return &p, nil +} diff --git a/protocol/packet/parser_test.go b/protocol/packet/parser_test.go new file mode 100644 index 0000000..6bc59b7 --- /dev/null +++ b/protocol/packet/parser_test.go @@ -0,0 +1,37 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package packet_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/bboozzoo/mconnect/protocol/packet" +) + +func TestParseFromData(t *testing.T) { + p, err := packet.FromData([]byte(`foobar`)) + assert.Error(t, err) + + p, err = packet.FromData([]byte(`{}`)) + assert.Error(t, err) + + p, err = packet.FromData([]byte(`{"id": 123, "type": "foo","body":{}}`)) + assert.NoError(t, err) + assert.NotNil(t, p) + assert.Equal(t, p, &packet.Packet{ + Id: uint64(123), + Type: "foo", + Body: []byte("{}"), + }) +}