blob: e74ec4a1c620750a33ece7147428157fc7569b5f [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"
21 "errors"
22 "fmt"
23 "github.com/google/gopacket"
24 "github.com/opencord/omci-lib-go"
25 log "github.com/sirupsen/logrus"
26)
27
28// ParseOpenOltOmciPacket receive an OMCI packet in the openolt format and returns
29// an OMCI Layer as per omci-lib-go
30func ParseOpenOltOmciPacket(pkt []byte) (gopacket.Packet, *omci.OMCI, error) {
31 rxMsg := hexDecode(pkt)
32
33 // NOTE this is may not be needed, VOLTHA sends the correct message
34 if len(rxMsg) >= 44 {
35 trailerLenData := rxMsg[42:44]
36 trailerLen := binary.BigEndian.Uint16(trailerLenData)
37 if trailerLen != 40 { // invalid base Format entry -> autocorrect
38 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
39 omciLogger.Trace("cc-corrected-omci-message: trailer len inserted")
40 }
41 } else {
42 omciLogger.WithFields(log.Fields{"Length": len(rxMsg)}).Error("received omci-message too small for OmciBaseFormat - abort")
43 return nil, nil, errors.New("received omci-message too small for OmciBaseFormat - abort")
44 }
45
46 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
47 if packet == nil {
48 omciLogger.Error("omci-message could not be decoded")
49 return nil, nil, errors.New("omci-message could not be decoded")
50 }
51 omciLayer := packet.Layer(omci.LayerTypeOMCI)
52 if omciLayer == nil {
53 omciLogger.Error("omci-message could not decode omci layer")
54 return nil, nil, fmt.Errorf("omci-message could not decode omci layer")
55 }
56 parsed, ok := omciLayer.(*omci.OMCI)
57 if !ok {
58 omciLogger.Error("omci-message could not assign omci layer")
59 return nil, nil, errors.New("omci-message could not assign omci layer")
60 }
61
62 return packet, parsed, nil
63}
64
65// hexDecode converts the hex encoding to binary
66func hexDecode(pkt []byte) []byte {
67 p := make([]byte, len(pkt)/2)
68 for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
69 // Go figure this ;)
70 u := (pkt[i] & 15) + (pkt[i]>>6)*9
71 l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
72 p[j] = u<<4 + l
73 }
74 return p
75}