blob: aa3a61126115a1ff8827c3eafd2052d396780cf7 [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"
24 "github.com/google/gopacket"
Andrea Campanella10426e22021-10-15 17:58:04 +020025 "github.com/opencord/omci-lib-go/v2"
Matteo Scandolof9d43412021-01-12 11:11:34 -080026 log "github.com/sirupsen/logrus"
27)
28
29// ParseOpenOltOmciPacket receive an OMCI packet in the openolt format and returns
30// an OMCI Layer as per omci-lib-go
31func ParseOpenOltOmciPacket(pkt []byte) (gopacket.Packet, *omci.OMCI, error) {
Matteo Scandolocedde462021-03-09 17:37:16 -080032 rxMsg := HexDecode(pkt)
Matteo Scandolof9d43412021-01-12 11:11:34 -080033
34 // NOTE this is may not be needed, VOLTHA sends the correct message
35 if len(rxMsg) >= 44 {
36 trailerLenData := rxMsg[42:44]
37 trailerLen := binary.BigEndian.Uint16(trailerLenData)
38 if trailerLen != 40 { // invalid base Format entry -> autocorrect
39 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
40 omciLogger.Trace("cc-corrected-omci-message: trailer len inserted")
41 }
42 } else {
43 omciLogger.WithFields(log.Fields{"Length": len(rxMsg)}).Error("received omci-message too small for OmciBaseFormat - abort")
44 return nil, nil, errors.New("received omci-message too small for OmciBaseFormat - abort")
45 }
46
47 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
48 if packet == nil {
49 omciLogger.Error("omci-message could not be decoded")
50 return nil, nil, errors.New("omci-message could not be decoded")
51 }
52 omciLayer := packet.Layer(omci.LayerTypeOMCI)
53 if omciLayer == nil {
54 omciLogger.Error("omci-message could not decode omci layer")
55 return nil, nil, fmt.Errorf("omci-message could not decode omci layer")
56 }
57 parsed, ok := omciLayer.(*omci.OMCI)
58 if !ok {
59 omciLogger.Error("omci-message could not assign omci layer")
60 return nil, nil, errors.New("omci-message could not assign omci layer")
61 }
62
63 return packet, parsed, nil
64}
65
Matteo Scandolocedde462021-03-09 17:37:16 -080066// HexDecode converts the hex encoding to binary
67func HexDecode(pkt []byte) []byte {
Matteo Scandolof9d43412021-01-12 11:11:34 -080068 p := make([]byte, len(pkt)/2)
69 for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
70 // Go figure this ;)
71 u := (pkt[i] & 15) + (pkt[i]>>6)*9
72 l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
73 p[j] = u<<4 + l
74 }
75 return p
76}
Matteo Scandolo992a23e2021-02-04 15:35:04 -080077
78//HexEncode convert binary to hex
79func HexEncode(omciPkt []byte) ([]byte, error) {
80 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
81 hex.Encode(dst, omciPkt)
82 return dst, nil
83}