blob: 29cd4235eb7557022bed4166bcc50fc050b8354e [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 Newtonb437c6f2019-12-18 11:51:57 -050026 pb "github.com/opencord/voltha-protos/v2/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)
Don Newtonb437c6f2019-12-18 11:51:57 -050058 return
Don Newton98fd8812019-09-23 15:15:02 -040059 }
60 for {
61 if client.KeepRunning {
62 connection, e := net.DialTCP("tcp", nil, raddr)
63 conn = connection
64 if e != nil {
65 log.Fatalf("unable to connect to %v", raddr)
66 }
67 defer conn.Close()
Don Newtonb437c6f2019-12-18 11:51:57 -050068 client.sayHello()
Don Newton98fd8812019-09-23 15:15:02 -040069 for {
Don Newtonb437c6f2019-12-18 11:51:57 -050070 if !client.KeepRunning {
71 return
72 }
Don Newton98fd8812019-09-23 15:15:02 -040073 buf := make([]byte, 1500)
74 read, e := conn.Read(buf)
75 if e != nil {
76 log.Printf("Connection has died %v", e)
77 break
78 }
79 decoder := goloxi.NewDecoder(buf)
Don Newton98fd8812019-09-23 15:15:02 -040080 header, e := ofp.DecodeHeader(decoder)
Don Newton98fd8812019-09-23 15:15:02 -040081
82 if e != nil {
83 log.Printf("decodeheader threw error %v", e)
84 }
85 message, _ := json.Marshal(header)
86 log.Printf("message %s\n", message)
87 client.parseHeader(header, buf) //first one is ready
88 len := header.GetLength()
89 if len < uint16(read) {
Don Newton98fd8812019-09-23 15:15:02 -040090 for {
91 read = read - int(len)
92 newBuf := buf[len:]
93 decoder = goloxi.NewDecoder(newBuf)
94 newHeader, e := ofp.DecodeHeader(decoder)
95 message, _ := json.Marshal(newHeader)
96 log.Printf("message %s\n", message)
97 if e != nil {
98
99 }
100 len = newHeader.GetLength()
101 client.parseHeader(newHeader, newBuf)
102 if read == int(len) {
Don Newton98fd8812019-09-23 15:15:02 -0400103 break
104 } else {
Don Newton98fd8812019-09-23 15:15:02 -0400105 }
106 buf = newBuf
107 }
108 }
109 if e != nil {
110 log.Println("Decode Header error ", e)
111 }
112 }
113 }
114 break
115 }
116}
Don Newtonb437c6f2019-12-18 11:51:57 -0500117func (client *Client) sayHello() {
Don Newton98fd8812019-09-23 15:15:02 -0400118
Don Newtonb437c6f2019-12-18 11:51:57 -0500119 hello := ofp.NewHello()
120 hello.Xid = uint32(GetXid())
121 var elements []ofp.IHelloElem
122
123 elem := ofp.NewHelloElemVersionbitmap()
124 elem.SetType(ofp.OFPHETVersionbitmap)
125 elem.SetLength(8)
126 var bitmap = ofp.Uint32{Value: 16}
127 bitmaps := []*ofp.Uint32{&bitmap}
128
129 elem.SetBitmaps(bitmaps)
130
131 elements = append(elements, elem)
132
133 hello.SetElements(elements)
134 e := client.SendMessage(hello)
135 if e != nil {
136 log.Fatal(e)
137 }
138}
Don Newton98fd8812019-09-23 15:15:02 -0400139func (client *Client) parseHeader(header ofp.IHeader, buf []byte) {
Don Newton98fd8812019-09-23 15:15:02 -0400140 switch header.GetType() {
Don Newtone0d34a82019-11-14 10:58:06 -0500141 case ofp.OFPTHello:
Don Newtonb437c6f2019-12-18 11:51:57 -0500142 //x := header.(*ofp.Hello)
Don Newtone0d34a82019-11-14 10:58:06 -0500143 case ofp.OFPTError:
Don Newton98fd8812019-09-23 15:15:02 -0400144 errMsg := header.(*ofp.ErrorMsg)
145 go handleErrMsg(errMsg)
Don Newtone0d34a82019-11-14 10:58:06 -0500146 case ofp.OFPTEchoRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400147 echoReq := header.(*ofp.EchoRequest)
148 go handleEchoRequest(echoReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500149 case ofp.OFPTEchoReply:
150 case ofp.OFPTExperimenter:
151 case ofp.OFPTFeaturesRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400152 featReq := header.(*ofp.FeaturesRequest)
153 go handleFeatureRequest(featReq, client.DeviceId, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500154 case ofp.OFPTFeaturesReply:
155 case ofp.OFPTGetConfigRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400156 configReq := header.(*ofp.GetConfigRequest)
157 go handleGetConfigRequest(configReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500158 case ofp.OFPTGetConfigReply:
159 case ofp.OFPTSetConfig:
Don Newton98fd8812019-09-23 15:15:02 -0400160 setConf := header.(*ofp.SetConfig)
161 go handleSetConfig(setConf)
Don Newtone0d34a82019-11-14 10:58:06 -0500162 case ofp.OFPTPacketIn:
163 case ofp.OFPTFlowRemoved:
164 case ofp.OFPTPortStatus:
165 case ofp.OFPTPacketOut:
Don Newton98fd8812019-09-23 15:15:02 -0400166 packetOut := header.(*ofp.PacketOut)
167 go handlePacketOut(packetOut, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500168 case ofp.OFPTFlowMod:
Don Newton98fd8812019-09-23 15:15:02 -0400169 flowModType := uint8(buf[25])
170 switch flowModType {
Don Newtone0d34a82019-11-14 10:58:06 -0500171 case ofp.OFPFCAdd:
Don Newton98fd8812019-09-23 15:15:02 -0400172 flowAdd := header.(*ofp.FlowAdd)
173 go handleFlowAdd(flowAdd, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500174 case ofp.OFPFCModify:
Don Newton98fd8812019-09-23 15:15:02 -0400175 flowMod := header.(*ofp.FlowMod)
176 go handleFlowMod(flowMod, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500177 case ofp.OFPFCModifyStrict:
Don Newton98fd8812019-09-23 15:15:02 -0400178 flowModStrict := header.(*ofp.FlowModifyStrict)
179 go handleFlowModStrict(flowModStrict, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500180 case ofp.OFPFCDelete:
Don Newton98fd8812019-09-23 15:15:02 -0400181 flowDelete := header.(*ofp.FlowDelete)
182 go handleFlowDelete(flowDelete, client.DeviceId)
Don Newtone0d34a82019-11-14 10:58:06 -0500183 case ofp.OFPFCDeleteStrict:
Don Newton98fd8812019-09-23 15:15:02 -0400184 flowDeleteStrict := header.(*ofp.FlowDeleteStrict)
185 go handleFlowDeleteStrict(flowDeleteStrict, client.DeviceId)
Don Newton98fd8812019-09-23 15:15:02 -0400186 }
Don Newtone0d34a82019-11-14 10:58:06 -0500187 case ofp.OFPTStatsRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400188 var statType = uint16(buf[8])<<8 + uint16(buf[9])
189 log.Println("statsType", statType)
190 go handleStatsRequest(header, statType, client.DeviceId, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500191 case ofp.OFPTBarrierRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400192 barRequest := header.(*ofp.BarrierRequest)
193 go handleBarrierRequest(barRequest, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500194 case ofp.OFPTRoleRequest:
Don Newton98fd8812019-09-23 15:15:02 -0400195 roleReq := header.(*ofp.RoleRequest)
196 go handleRoleRequest(roleReq, client)
Don Newtone0d34a82019-11-14 10:58:06 -0500197 case ofp.OFPTMeterMod:
198 meterMod := header.(*ofp.MeterMod)
199 go handleMeterModRequest(meterMod, client)
Don Newton98fd8812019-09-23 15:15:02 -0400200
201 }
202}
203
204//openFlowMessage created to allow for a single SendMessage
205type OpenFlowMessage interface {
206 Serialize(encoder *goloxi.Encoder) error
207}
208
209func (client *Client) SendMessage(message OpenFlowMessage) error {
210 jsonMessage, _ := json.Marshal(message)
211 log.Printf("send message called %s\n", jsonMessage)
212 enc := goloxi.NewEncoder()
213 message.Serialize(enc)
214 jMessage, _ := json.Marshal(message)
Don Newtone0d34a82019-11-14 10:58:06 -0500215 bytes := enc.Bytes()
216 log.Printf("message after serialize %d for message %s", bytes, jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400217
218 for {
219 if conn == nil {
220 log.Println("CONN IS NIL")
221 time.Sleep(10 * time.Millisecond)
222 } else {
223 break
224 }
225 }
Don Newtone0d34a82019-11-14 10:58:06 -0500226 _, err := conn.Write(bytes)
Don Newton98fd8812019-09-23 15:15:02 -0400227 if err != nil {
Don Newtone0d34a82019-11-14 10:58:06 -0500228 log.Printf("SendMessage had error %v \n %s\n********", err, jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400229 return err
Don Newtone0d34a82019-11-14 10:58:06 -0500230 } else {
231 log.Printf("message after send %s", jMessage)
Don Newton98fd8812019-09-23 15:15:02 -0400232 }
233 return nil
234}
235func SetGrpcClient(client *pb.VolthaServiceClient) {
236 volthaClient = client
237}
238func getGrpcClient() *pb.VolthaServiceClient {
239 return volthaClient
240}
241func test(hello ofp.IHello) {
242 fmt.Println("works")
243}
244func SetPacketOutChannel(pktOutChan chan pb.PacketOut) {
245 packetOutChannel = pktOutChan
246}