First Commit of Voltha-Go-Controller from Radisys
Change-Id: I8e2e908e7ab09a4fe3d86849da18b6d69dcf4ab0
diff --git a/vendor/github.com/google/gopacket/layers/lcm.go b/vendor/github.com/google/gopacket/layers/lcm.go
new file mode 100644
index 0000000..58a4b82
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/lcm.go
@@ -0,0 +1,218 @@
+// Copyright 2018 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+const (
+ // LCMShortHeaderMagic is the LCM small message header magic number
+ LCMShortHeaderMagic uint32 = 0x4c433032
+ // LCMFragmentedHeaderMagic is the LCM fragmented message header magic number
+ LCMFragmentedHeaderMagic uint32 = 0x4c433033
+)
+
+// LCM (Lightweight Communications and Marshalling) is a set of libraries and
+// tools for message passing and data marshalling, targeted at real-time systems
+// where high-bandwidth and low latency are critical. It provides a
+// publish/subscribe message passing model and automatic
+// marshalling/unmarshalling code generation with bindings for applications in a
+// variety of programming languages.
+//
+// References
+// https://lcm-proj.github.io/
+// https://github.com/lcm-proj/lcm
+type LCM struct {
+ // Common (short & fragmented header) fields
+ Magic uint32
+ SequenceNumber uint32
+ // Fragmented header only fields
+ PayloadSize uint32
+ FragmentOffset uint32
+ FragmentNumber uint16
+ TotalFragments uint16
+ // Common field
+ ChannelName string
+ // Gopacket helper fields
+ Fragmented bool
+ fingerprint LCMFingerprint
+ contents []byte
+ payload []byte
+}
+
+// LCMFingerprint is the type of a LCM fingerprint.
+type LCMFingerprint uint64
+
+var (
+ // lcmLayerTypes contains a map of all LCM fingerprints that we support and
+ // their LayerType
+ lcmLayerTypes = map[LCMFingerprint]gopacket.LayerType{}
+ layerTypeIndex = 1001
+)
+
+// RegisterLCMLayerType allows users to register decoders for the underlying
+// LCM payload. This is done based on the fingerprint that every LCM message
+// contains and which identifies it uniquely. If num is not the zero value it
+// will be used when registering with RegisterLayerType towards gopacket,
+// otherwise an incremental value starting from 1001 will be used.
+func RegisterLCMLayerType(num int, name string, fingerprint LCMFingerprint,
+ decoder gopacket.Decoder) gopacket.LayerType {
+ metadata := gopacket.LayerTypeMetadata{Name: name, Decoder: decoder}
+
+ if num == 0 {
+ num = layerTypeIndex
+ layerTypeIndex++
+ }
+
+ lcmLayerTypes[fingerprint] = gopacket.RegisterLayerType(num, metadata)
+
+ return lcmLayerTypes[fingerprint]
+}
+
+// SupportedLCMFingerprints returns a slice of all LCM fingerprints that has
+// been registered so far.
+func SupportedLCMFingerprints() []LCMFingerprint {
+ fingerprints := make([]LCMFingerprint, 0, len(lcmLayerTypes))
+ for fp := range lcmLayerTypes {
+ fingerprints = append(fingerprints, fp)
+ }
+ return fingerprints
+}
+
+// GetLCMLayerType returns the underlying LCM message's LayerType.
+// This LayerType has to be registered by using RegisterLCMLayerType.
+func GetLCMLayerType(fingerprint LCMFingerprint) gopacket.LayerType {
+ layerType, ok := lcmLayerTypes[fingerprint]
+ if !ok {
+ return gopacket.LayerTypePayload
+ }
+
+ return layerType
+}
+
+func decodeLCM(data []byte, p gopacket.PacketBuilder) error {
+ lcm := &LCM{}
+
+ err := lcm.DecodeFromBytes(data, p)
+ if err != nil {
+ return err
+ }
+
+ p.AddLayer(lcm)
+ p.SetApplicationLayer(lcm)
+
+ return p.NextDecoder(lcm.NextLayerType())
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (lcm *LCM) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+ if len(data) < 8 {
+ df.SetTruncated()
+ return errors.New("LCM < 8 bytes")
+ }
+ offset := 0
+
+ lcm.Magic = binary.BigEndian.Uint32(data[offset:4])
+ offset += 4
+
+ if lcm.Magic != LCMShortHeaderMagic && lcm.Magic != LCMFragmentedHeaderMagic {
+ return fmt.Errorf("Received LCM header magic %v does not match know "+
+ "LCM magic numbers. Dropping packet.", lcm.Magic)
+ }
+
+ lcm.SequenceNumber = binary.BigEndian.Uint32(data[offset:8])
+ offset += 4
+
+ if lcm.Magic == LCMFragmentedHeaderMagic {
+ lcm.Fragmented = true
+
+ lcm.PayloadSize = binary.BigEndian.Uint32(data[offset : offset+4])
+ offset += 4
+
+ lcm.FragmentOffset = binary.BigEndian.Uint32(data[offset : offset+4])
+ offset += 4
+
+ lcm.FragmentNumber = binary.BigEndian.Uint16(data[offset : offset+2])
+ offset += 2
+
+ lcm.TotalFragments = binary.BigEndian.Uint16(data[offset : offset+2])
+ offset += 2
+ } else {
+ lcm.Fragmented = false
+ }
+
+ if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
+ buffer := make([]byte, 0)
+ for _, b := range data[offset:] {
+ offset++
+
+ if b == 0 {
+ break
+ }
+
+ buffer = append(buffer, b)
+ }
+
+ lcm.ChannelName = string(buffer)
+ }
+
+ lcm.fingerprint = LCMFingerprint(
+ binary.BigEndian.Uint64(data[offset : offset+8]))
+
+ lcm.contents = data[:offset]
+ lcm.payload = data[offset:]
+
+ return nil
+}
+
+// CanDecode returns a set of layers that LCM objects can decode.
+// As LCM objects can only decode the LCM layer, we just return that layer.
+func (lcm LCM) CanDecode() gopacket.LayerClass {
+ return LayerTypeLCM
+}
+
+// NextLayerType specifies the LCM payload layer type following this header.
+// As LCM packets are serialized structs with uniq fingerprints for each uniq
+// combination of data types, lookup of correct layer type is based on that
+// fingerprint.
+func (lcm LCM) NextLayerType() gopacket.LayerType {
+ if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
+ return GetLCMLayerType(lcm.fingerprint)
+ }
+
+ return gopacket.LayerTypeFragment
+}
+
+// LayerType returns LayerTypeLCM
+func (lcm LCM) LayerType() gopacket.LayerType {
+ return LayerTypeLCM
+}
+
+// LayerContents returns the contents of the LCM header.
+func (lcm LCM) LayerContents() []byte {
+ return lcm.contents
+}
+
+// LayerPayload returns the payload following this LCM header.
+func (lcm LCM) LayerPayload() []byte {
+ return lcm.payload
+}
+
+// Payload returns the payload following this LCM header.
+func (lcm LCM) Payload() []byte {
+ return lcm.LayerPayload()
+}
+
+// Fingerprint returns the LCM fingerprint of the underlying message.
+func (lcm LCM) Fingerprint() LCMFingerprint {
+ return lcm.fingerprint
+}