blob: 2c150a565c1d4eeb099617a15919eef14fd24bd0 [file] [log] [blame]
Matteo Scandolof9d43412021-01-12 11:11:34 -08001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package omci
18
19import (
20 "encoding/binary"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080021 "encoding/hex"
Matteo Scandolof9d43412021-01-12 11:11:34 -080022 "errors"
23 "fmt"
Holger Hildebrandt02101a62022-04-06 13:00:51 +000024
Matteo Scandolof9d43412021-01-12 11:11:34 -080025 "github.com/google/gopacket"
Andrea Campanella10426e22021-10-15 17:58:04 +020026 "github.com/opencord/omci-lib-go/v2"
Matteo Scandolof9d43412021-01-12 11:11:34 -080027 log "github.com/sirupsen/logrus"
28)
29
Holger Hildebrandt02101a62022-04-06 13:00:51 +000030const DeviceIdentifierPos = 3
31
Matteo Scandolof9d43412021-01-12 11:11:34 -080032// ParseOpenOltOmciPacket receive an OMCI packet in the openolt format and returns
33// an OMCI Layer as per omci-lib-go
34func ParseOpenOltOmciPacket(pkt []byte) (gopacket.Packet, *omci.OMCI, error) {
Matteo Scandolocedde462021-03-09 17:37:16 -080035 rxMsg := HexDecode(pkt)
Holger Hildebrandt02101a62022-04-06 13:00:51 +000036 if len(rxMsg) < 10 {
37 omciLogger.WithFields(log.Fields{"Length": len(rxMsg)}).Error("received omci message is generally too small - abort")
38 return nil, nil, errors.New("received omci message is generally too small - abort")
39 }
40 if rxMsg[DeviceIdentifierPos] == byte(omci.BaselineIdent) {
41 // NOTE this is may not be needed, VOLTHA sends the correct message
42 if len(rxMsg) >= 44 {
43 trailerLenData := rxMsg[42:44]
44 trailerLen := binary.BigEndian.Uint16(trailerLenData)
45 if trailerLen != 40 { // invalid base Format entry -> autocorrect
46 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
47 omciLogger.Trace("cc-corrected-omci-message: trailer len inserted")
48 }
49 } else {
50 omciLogger.WithFields(log.Fields{"Length": len(rxMsg)}).Error("received omci-message too small for OmciBaseFormat - abort")
51 return nil, nil, errors.New("received omci-message too small for OmciBaseFormat - abort")
52 }
53 } else if rxMsg[DeviceIdentifierPos] == byte(omci.ExtendedIdent) {
54 if len(rxMsg) > 1980 {
55 omciLogger.WithFields(log.Fields{"Length": len(rxMsg)}).Error("received omci-message with wrong length for OmciExtendedFormat - abort")
56 return nil, nil, errors.New("received omci-message with wrong length for OmciExtendedFormat - abort")
Matteo Scandolof9d43412021-01-12 11:11:34 -080057 }
58 } else {
Holger Hildebrandt02101a62022-04-06 13:00:51 +000059 omciLogger.WithFields(log.Fields{"DeviceIdent": rxMsg[DeviceIdentifierPos]}).Error("received omci-message with wrong Device Identifier - abort")
60 return nil, nil, errors.New("received omci-message with wrong Device Identifier - abort")
Matteo Scandolof9d43412021-01-12 11:11:34 -080061 }
62
63 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
64 if packet == nil {
65 omciLogger.Error("omci-message could not be decoded")
66 return nil, nil, errors.New("omci-message could not be decoded")
67 }
68 omciLayer := packet.Layer(omci.LayerTypeOMCI)
69 if omciLayer == nil {
70 omciLogger.Error("omci-message could not decode omci layer")
71 return nil, nil, fmt.Errorf("omci-message could not decode omci layer")
72 }
73 parsed, ok := omciLayer.(*omci.OMCI)
74 if !ok {
75 omciLogger.Error("omci-message could not assign omci layer")
76 return nil, nil, errors.New("omci-message could not assign omci layer")
77 }
78
79 return packet, parsed, nil
80}
81
Matteo Scandolocedde462021-03-09 17:37:16 -080082// HexDecode converts the hex encoding to binary
83func HexDecode(pkt []byte) []byte {
Matteo Scandolof9d43412021-01-12 11:11:34 -080084 p := make([]byte, len(pkt)/2)
85 for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
86 // Go figure this ;)
87 u := (pkt[i] & 15) + (pkt[i]>>6)*9
88 l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
89 p[j] = u<<4 + l
90 }
91 return p
92}
Matteo Scandolo992a23e2021-02-04 15:35:04 -080093
94//HexEncode convert binary to hex
95func HexEncode(omciPkt []byte) ([]byte, error) {
96 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
97 hex.Encode(dst, omciPkt)
98 return dst, nil
99}