blob: f7e3b721ea7ca3ac69850fcdfb37b0177e13256a [file] [log] [blame]
Don Newton98fd8812019-09-23 15:15:02 -04001/*
2 Copyright 2017 the original author or authors.
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 openflow
18
19import (
20 "encoding/json"
21 "fmt"
22 "time"
23
Don Newtone0d34a82019-11-14 10:58:06 -050024 "github.com/donNewtonAlpha/goloxi"
25 ofp "github.com/donNewtonAlpha/goloxi/of13"
Don Newton98fd8812019-09-23 15:15:02 -040026 pb "github.com/opencord/voltha-protos/go/voltha"
Don Newton98fd8812019-09-23 15:15:02 -040027
28 "log"
29 "net"
30)
31
32var conn net.Conn
33var volthaClient *pb.VolthaServiceClient
34var packetOutChannel chan pb.PacketOut
35
36type Client struct {
37 OfServerAddress string
38 Port uint16
39 DeviceId string
40 KeepRunning bool
41}
42
43func NewClient(ofServerAddress string, port uint16, deviceId string, keepRunning bool) *Client {
44 client := Client{OfServerAddress: ofServerAddress, Port: port, DeviceId: deviceId, KeepRunning: keepRunning}
45 go client.Start()
46 return &client
47}
48
49func (client *Client) End() {
50 client.KeepRunning = false
51}
52func (client *Client) Start() {
53 addressLine := fmt.Sprintf("%s:%d", client.OfServerAddress, client.Port)
54 raddr, e := net.ResolveTCPAddr("tcp", addressLine)
55 if e != nil {
56 errMessage := fmt.Errorf("Unable to resolve %s", addressLine)
57 fmt.Println(errMessage)
58 }
59 for {
60 if client.KeepRunning {
61 connection, e := net.DialTCP("tcp", nil, raddr)
62 conn = connection
63 if e != nil {
64 log.Fatalf("unable to connect to %v", raddr)
65 }
66 defer conn.Close()
67 hello := ofp.NewHello()
68 hello.Xid = uint32(GetXid())
69 var elements []ofp.IHelloElem
70
71 elem := ofp.NewHelloElemVersionbitmap()
72 elem.SetType(ofp.OFPHETVersionbitmap)
73 elem.SetLength(8)
74 var bitmap = ofp.Uint32{Value: 16}
75 bitmaps := []*ofp.Uint32{&bitmap}
76
77 elem.SetBitmaps(bitmaps)
78
79 elements = append(elements, elem)
80
81 hello.SetElements(elements)
82 e = client.SendMessage(hello)
83 if e != nil {
84 log.Fatal(e)
85 }
86 for {
87 buf := make([]byte, 1500)
88 read, e := conn.Read(buf)
89 if e != nil {
90 log.Printf("Connection has died %v", e)
91 break
92 }
93 decoder := goloxi.NewDecoder(buf)
94 log.Printf("decoder offset %d baseOffset %d", decoder.Offset(), decoder.BaseOffset())
95 header, e := ofp.DecodeHeader(decoder)
96 log.Printf("received packet read: %d", read)
97
98 if e != nil {
99 log.Printf("decodeheader threw error %v", e)
100 }
101 message, _ := json.Marshal(header)
102 log.Printf("message %s\n", message)
103 client.parseHeader(header, buf) //first one is ready
104 len := header.GetLength()
105 if len < uint16(read) {
106 log.Printf("Len %d was less than read %d", len, read)
107 for {
108 read = read - int(len)
109 newBuf := buf[len:]
110 decoder = goloxi.NewDecoder(newBuf)
111 newHeader, e := ofp.DecodeHeader(decoder)
112 message, _ := json.Marshal(newHeader)
113 log.Printf("message %s\n", message)
114 if e != nil {
115
116 }
117 len = newHeader.GetLength()
118 client.parseHeader(newHeader, newBuf)
119 if read == int(len) {
120 log.Printf(" not continuing read %d len %d", read, len)
121 break
122 } else {
123 log.Printf("continuing read %d len %d", read, len)
124 }
125 buf = newBuf
126 }
127 }
128 if e != nil {
129 log.Println("Decode Header error ", e)
130 }
131 }
132 }
133 break
134 }
135}
136
137func (client *Client) parseHeader(header ofp.IHeader, buf []byte) {
138
139 log.Printf("parseHeader called with type %d", header.GetType())
140 switch header.GetType() {
Don Newtone0d34a82019-11-14 10:58:06 -0500141 case ofp.OFPTHello:
Don Newton98fd8812019-09-23 15:15:02 -0400142 x := header.(*ofp.Hello)
143 log.Printf("helloMessage : %+v", x)
Don Newtone0d34a82019-11-14 10:58:06 -0500144 case ofp.OFPTError:
Don Newton98fd8812019-09-23 15:15:02 -0400145 errMsg := header.(*ofp.ErrorMsg)
146 go handleErrMsg(errMsg)
Don Newtone0d34a82019-11-14 10:58:06 -0500147 case ofp.OFPTEchoRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400148 echoReq := header.(*ofp.EchoRequest)
149 go handleEchoRequest(echoReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500150 case ofp.OFPTEchoReply:
151 case ofp.OFPTExperimenter:
152 case ofp.OFPTFeaturesRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400153 featReq := header.(*ofp.FeaturesRequest)
154 go handleFeatureRequest(featReq, client.DeviceId, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500155 case ofp.OFPTFeaturesReply:
156 case ofp.OFPTGetConfigRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400157 configReq := header.(*ofp.GetConfigRequest)
158 go handleGetConfigRequest(configReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500159 case ofp.OFPTGetConfigReply:
160 case ofp.OFPTSetConfig:
Don Newton98fd8812019-09-23 15:15:02 -0400161 setConf := header.(*ofp.SetConfig)
162 go handleSetConfig(setConf)
Don Newtone0d34a82019-11-14 10:58:06 -0500163 case ofp.OFPTPacketIn:
164 case ofp.OFPTFlowRemoved:
165 case ofp.OFPTPortStatus:
166 case ofp.OFPTPacketOut:
Don Newton98fd8812019-09-23 15:15:02 -0400167 packetOut := header.(*ofp.PacketOut)
168 go handlePacketOut(packetOut, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500169 case ofp.OFPTFlowMod:
Don Newton98fd8812019-09-23 15:15:02 -0400170 flowModType := uint8(buf[25])
171 switch flowModType {
Don Newtone0d34a82019-11-14 10:58:06 -0500172 case ofp.OFPFCAdd:
Don Newton98fd8812019-09-23 15:15:02 -0400173 flowAdd := header.(*ofp.FlowAdd)
174 go handleFlowAdd(flowAdd, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500175 case ofp.OFPFCModify:
Don Newton98fd8812019-09-23 15:15:02 -0400176 flowMod := header.(*ofp.FlowMod)
177 go handleFlowMod(flowMod, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500178 case ofp.OFPFCModifyStrict:
Don Newton98fd8812019-09-23 15:15:02 -0400179 flowModStrict := header.(*ofp.FlowModifyStrict)
180 go handleFlowModStrict(flowModStrict, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500181 case ofp.OFPFCDelete:
Don Newton98fd8812019-09-23 15:15:02 -0400182 flowDelete := header.(*ofp.FlowDelete)
183 go handleFlowDelete(flowDelete, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500184 case ofp.OFPFCDeleteStrict:
Don Newton98fd8812019-09-23 15:15:02 -0400185 flowDeleteStrict := header.(*ofp.FlowDeleteStrict)
186 go handleFlowDeleteStrict(flowDeleteStrict, client.DeviceId)
Don Newton98fd8812019-09-23 15:15:02 -0400187 }
Don Newtone0d34a82019-11-14 10:58:06 -0500188 case ofp.OFPTStatsRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400189 var statType = uint16(buf[8])<<8 + uint16(buf[9])
190 log.Println("statsType", statType)
191 go handleStatsRequest(header, statType, client.DeviceId, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500192 case ofp.OFPTBarrierRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400193 barRequest := header.(*ofp.BarrierRequest)
194 go handleBarrierRequest(barRequest, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500195 case ofp.OFPTRoleRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400196 roleReq := header.(*ofp.RoleRequest)
197 go handleRoleRequest(roleReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500198 case ofp.OFPTMeterMod:
199 meterMod := header.(*ofp.MeterMod)
200 go handleMeterModRequest(meterMod, client)
Don Newton98fd8812019-09-23 15:15:02 -0400201
202 }
203}
204
205//openFlowMessage created to allow for a single SendMessage
206type OpenFlowMessage interface {
207 Serialize(encoder *goloxi.Encoder) error
208}
209
210func (client *Client) SendMessage(message OpenFlowMessage) error {
211 jsonMessage, _ := json.Marshal(message)
212 log.Printf("send message called %s\n", jsonMessage)
213 enc := goloxi.NewEncoder()
214 message.Serialize(enc)
215 jMessage, _ := json.Marshal(message)
Don Newtone0d34a82019-11-14 10:58:06 -0500216 bytes := enc.Bytes()
217 log.Printf("message after serialize %d for message %s", bytes, jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400218
219 for {
220 if conn == nil {
221 log.Println("CONN IS NIL")
222 time.Sleep(10 * time.Millisecond)
223 } else {
224 break
225 }
226 }
Don Newtone0d34a82019-11-14 10:58:06 -0500227 _, err := conn.Write(bytes)
Don Newton98fd8812019-09-23 15:15:02 -0400228 if err != nil {
Don Newtone0d34a82019-11-14 10:58:06 -0500229 log.Printf("SendMessage had error %v \n %s\n********", err, jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400230 return err
Don Newtone0d34a82019-11-14 10:58:06 -0500231 } else {
232 log.Printf("message after send %s", jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400233 }
234 return nil
235}
236func SetGrpcClient(client *pb.VolthaServiceClient) {
237 volthaClient = client
238}
239func getGrpcClient() *pb.VolthaServiceClient {
240 return volthaClient
241}
242func test(hello ofp.IHello) {
243 fmt.Println("works")
244}
245func SetPacketOutChannel(pktOutChan chan pb.PacketOut) {
246 packetOutChannel = pktOutChan
247}