Skip to content

Commit

Permalink
Merge d5891bc into 01e10f1
Browse files Browse the repository at this point in the history
  • Loading branch information
itachi0 committed Nov 17, 2015
2 parents 01e10f1 + d5891bc commit 7de55c4
Show file tree
Hide file tree
Showing 3 changed files with 416 additions and 0 deletions.
57 changes: 57 additions & 0 deletions pkg/protocol/protocol.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package protocol

import (
"github.com/PandoCloud/pando-cloud/pkg/tlv"
)

type CommandTypeHead struct {
Flag uint8
Timestamp uint64
Token [16]byte
SubDeviceid uint16
CommandId uint16
Priority uint16
ParamsCount uint16
}

type CommandType struct {
Head CommandTypeHead
Params []tlv.TLV
}

type EventTypeHead struct {
Flag uint8
Timestamp uint64
Token [16]byte
SubDeviceid uint16
Eventid uint16
Priority uint16
ParamsCOunt uint16
}

type EventType struct {
Head EventTypeHead
Params []tlv.TLV
}

type DataTypeHead struct {
Flag uint8
Timestamp uint64
Token [16]byte
}

type DataType struct {
Head DataTypeHead
SubData []SubDataType
}

type SubDataTypeHead struct {
SubDeviceid uint16
PropertyNum uint16
ParamsCount uint16
}

type SubDataType struct {
Head SubDataTypeHead
Params []tlv.TLV
}
315 changes: 315 additions & 0 deletions pkg/tlv/tlv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
package tlv

import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
)

const (
TLV_FLOAT64 = 1
TLV_FLOAT32 = 2
TLV_INT8 = 3
TLV_INT16 = 4
TLV_INT32 = 5
TLV_INT64 = 6
TLV_UINT8 = 7
TLV_UINT16 = 8
TLV_UINT32 = 9
TLV_UINT64 = 10
TLV_BYTES = 11
TLV_URI = 12
TLV_BOOL = 13
)

type TLV struct {
Tag uint16
Value []byte
}

func Uint16ToByte(value uint16) []byte {
buf := bytes.NewBuffer([]byte{})
binary.Write(buf, binary.BigEndian, value)

return buf.Bytes()
}

func ByteToUint16(buf []byte) uint16 {
tmpBuf := bytes.NewBuffer(buf)
var value uint16
binary.Read(tmpBuf, binary.BigEndian, &value)

return value
}

func (tlv *TLV) ToBinary() []byte {
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, &tlv.Tag)
binary.Write(buf, binary.BigEndian, &tlv.Value)

return buf.Bytes()
}

func (tlv *TLV) Length() int {
length := int(0)
switch tlv.Tag {
case TLV_FLOAT64:
length = 8
case TLV_INT64:
length = 8
case TLV_UINT64:
length = 8
case TLV_FLOAT32:
length = 4
case TLV_INT32:
length = 4
case TLV_UINT32:
length = 4
case TLV_INT16:
length = 2
case TLV_UINT16:
length = 2
case TLV_INT8:
length = 1
case TLV_UINT8:
length = 1
case TLV_BYTES:
length = int(ByteToUint16(tlv.Value[0:2]))
length += 2
case TLV_URI:
length = int(ByteToUint16(tlv.Value[0:2]))
length += 2
default:
length = 0
}

length += 2

return length
}

func (tlv *TLV) FromBinary(r io.Reader) error {
binary.Read(r, binary.BigEndian, &tlv.Tag)
length := uint16(0)
switch tlv.Tag {
case TLV_FLOAT64:
length = 8
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_INT64:
length = 8
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_UINT64:
length = 8
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_FLOAT32:
length = 4
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_INT32:
length = 4
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_UINT32:
length = 4
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_INT16:
length = 2
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_UINT16:
length = 2
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_INT8:
length = 1
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_UINT8:
length = 1
tlv.Value = make([]byte, length)
binary.Read(r, binary.BigEndian, &tlv.Value)
case TLV_BYTES:
binary.Read(r, binary.BigEndian, &length)
tlv.Value = make([]byte, length+2)
copy(tlv.Value[0:2], Uint16ToByte(length))
binary.Read(r, binary.BigEndian, tlv.Value[2:])
case TLV_URI:
binary.Read(r, binary.BigEndian, &length)
tlv.Value = make([]byte, length+2)
copy(tlv.Value[0:2], Uint16ToByte(length))
binary.Read(r, binary.BigEndian, tlv.Value[2:])
default:
return errors.New(fmt.Sprintf("unsuport value: %d", tlv.Tag))
}

return nil
}

func MakeTLV(a interface{}) (*TLV, error) {
var tag uint16
var length uint16
buf := new(bytes.Buffer)
switch a.(type) {
case float64:
tag = TLV_FLOAT64
length = 8
binary.Write(buf, binary.BigEndian, a.(float64))
case float32:
tag = TLV_FLOAT32
length = 4
binary.Write(buf, binary.BigEndian, a.(float32))
case int8:
tag = TLV_INT8
length = 1
binary.Write(buf, binary.BigEndian, a.(int8))
case int16:
tag = TLV_INT16
length = 2
binary.Write(buf, binary.BigEndian, a.(int16))
case int32:
tag = TLV_INT32
length = 4
binary.Write(buf, binary.BigEndian, a.(int32))
case int64:
tag = TLV_INT64
length = 8
binary.Write(buf, binary.BigEndian, a.(int64))
case uint8:
tag = TLV_UINT8
length = 1
binary.Write(buf, binary.BigEndian, a.(uint8))
case uint16:
tag = TLV_UINT16
length = 2
binary.Write(buf, binary.BigEndian, a.(uint16))
case uint32:
tag = TLV_UINT32
length = 4
binary.Write(buf, binary.BigEndian, a.(uint32))
case uint64:
tag = TLV_UINT64
length = 8
binary.Write(buf, binary.BigEndian, a.(uint64))
case []byte:
tag = TLV_BYTES
length = uint16(len(a.([]byte)))
binary.Write(buf, binary.BigEndian, length)
binary.Write(buf, binary.BigEndian, a.([]byte))
case string:
tag = TLV_URI
length = uint16(len(a.(string)))
binary.Write(buf, binary.BigEndian, length)
binary.Write(buf, binary.BigEndian, []byte(a.(string)))
default:
return nil, errors.New(fmt.Sprintf("unsuport value: %v", a))
}

tlv := TLV{
Tag: tag,
Value: buf.Bytes(),
}

if length == 0 {
tlv.Value = []byte{}
}

return &tlv, nil
}

func ReadTLV(tlv *TLV) (interface{}, error) {
tag := tlv.Tag
length := uint16(0)
value := tlv.Value

buffer := bytes.NewReader(value)
switch tag {
case TLV_FLOAT64:
retvar := float64(0.0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_FLOAT32:
retvar := float32(0.0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_INT8:
retvar := int8(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_INT16:
retvar := int16(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_INT32:
retvar := int32(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_INT64:
retvar := int64(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_UINT8:
retvar := uint8(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_UINT16:
retvar := uint16(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_UINT32:
retvar := uint32(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_UINT64:
retvar := uint64(0)
err := binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_BYTES:
err := binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return []byte{}, err
}
retvar := make([]byte, length)
err = binary.Read(buffer, binary.BigEndian, &retvar)
return retvar, err
case TLV_URI:
err := binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return string([]byte{}), err
}
retvar := make([]byte, length)
err = binary.Read(buffer, binary.BigEndian, &retvar)
return string(retvar), err
default:
return nil, errors.New("Reading TLV error ,Unkown TLV type: " + string(tag))
}
}

func MakeTLVs(a []interface{}) ([]TLV, error) {
tlvs := []TLV{}
for _, one := range a {
tlv, err := MakeTLV(one)
if err != nil {
return nil, err
}
tlvs = append(tlvs, *tlv)
}
return tlvs, nil
}

func ReadTLVs(tlvs []TLV) ([]interface{}, error) {
values := []interface{}{}
for _, tlv := range tlvs {
one, err := ReadTLV(&tlv)
if err != nil {
return values, err
}
values = append(values, one)
}
return values, nil
}
Loading

0 comments on commit 7de55c4

Please sign in to comment.