"git.fd.io/govpp.git/adapter"
"git.fd.io/govpp.git/api"
+ "git.fd.io/govpp.git/codec"
"git.fd.io/govpp.git/core/bin_api/vpe"
)
type Connection struct {
vpp adapter.VppAdapter // VPP adapter
connected uint32 // non-zero if the adapter is connected to VPP
- codec *MsgCodec // message codec
+ codec *codec.MsgCodec // message codec
msgIDsLock sync.RWMutex // lock for the message IDs map
msgIDs map[string]uint16 // map of message IDs indexed by message name + CRC
- channelsLock sync.RWMutex // lock for the channels map
- channels map[uint16]*api.Channel // map of all API channels indexed by the channel ID
+ channelsLock sync.RWMutex // lock for the channels map
+ channels map[uint16]*channel // map of all API channels indexed by the channel ID
notifSubscriptionsLock sync.RWMutex // lock for the subscriptions map
notifSubscriptions map[uint16][]*api.NotifSubscription // map od all notification subscriptions indexed by message ID
conn = &Connection{
vpp: vppAdapter,
- codec: &MsgCodec{},
- channels: make(map[uint16]*api.Channel),
+ codec: &codec.MsgCodec{},
+ channels: make(map[uint16]*channel),
msgIDs: make(map[string]uint16),
notifSubscriptions: make(map[uint16][]*api.NotifSubscription),
}
// it continues with connectLoop and tries to reconnect.
func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) {
// create a separate API channel for health check probes
- ch, err := conn.NewAPIChannelBuffered(1, 1)
+ ch, err := conn.newAPIChannelBuffered(1, 1)
if err != nil {
log.Error("Failed to create health check API channel, health check will be disabled:", err)
return
// try draining probe replies from previous request before sending next one
select {
- case <-ch.ReplyChan:
+ case <-ch.replyChan:
log.Debug("drained old probe reply from reply channel")
default:
}
// send the control ping request
- ch.ReqChan <- &api.VppRequest{Message: msgControlPing}
+ ch.reqChan <- &api.VppRequest{Message: msgControlPing}
for {
// expect response within timeout period
select {
- case vppReply := <-ch.ReplyChan:
+ case vppReply := <-ch.replyChan:
err = vppReply.Error
case <-time.After(healthCheckReplyTimeout):
c.connectLoop(connChan)
}
-// NewAPIChannel returns a new API channel for communication with VPP via govpp core.
-// It uses default buffer sizes for the request and reply Go channels.
-func (c *Connection) NewAPIChannel() (*api.Channel, error) {
- if c == nil {
- return nil, errors.New("nil connection passed in")
- }
- return c.NewAPIChannelBuffered(requestChannelBufSize, replyChannelBufSize)
+func (c *Connection) NewAPIChannel() (api.Channel, error) {
+ return c.newAPIChannelBuffered(requestChannelBufSize, replyChannelBufSize)
+}
+
+func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (api.Channel, error) {
+ return c.newAPIChannelBuffered(reqChanBufSize, replyChanBufSize)
}
// NewAPIChannelBuffered returns a new API channel for communication with VPP via govpp core.
// It allows to specify custom buffer sizes for the request and reply Go channels.
-func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (*api.Channel, error) {
+func (c *Connection) newAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (*channel, error) {
if c == nil {
return nil, errors.New("nil connection passed in")
}
chID := uint16(atomic.AddUint32(&c.maxChannelID, 1) & 0x7fff)
- ch := api.NewChannelInternal(chID)
- ch.MsgDecoder = c.codec
- ch.MsgIdentifier = c
+ ch := &channel{
+ id: chID,
+ replyTimeout: defaultReplyTimeout,
+ }
+ ch.msgDecoder = c.codec
+ ch.msgIdentifier = c
// create the communication channels
- ch.ReqChan = make(chan *api.VppRequest, reqChanBufSize)
- ch.ReplyChan = make(chan *api.VppReply, replyChanBufSize)
- ch.NotifSubsChan = make(chan *api.NotifSubscribeRequest, reqChanBufSize)
- ch.NotifSubsReplyChan = make(chan error, replyChanBufSize)
+ ch.reqChan = make(chan *api.VppRequest, reqChanBufSize)
+ ch.replyChan = make(chan *api.VppReply, replyChanBufSize)
+ ch.notifSubsChan = make(chan *api.NotifSubscribeRequest, reqChanBufSize)
+ ch.notifSubsReplyChan = make(chan error, replyChanBufSize)
// store API channel within the client
c.channelsLock.Lock()
}
// releaseAPIChannel releases API channel that needs to be closed.
-func (c *Connection) releaseAPIChannel(ch *api.Channel) {
+func (c *Connection) releaseAPIChannel(ch *channel) {
log.WithFields(logger.Fields{
- "ID": ch.ID,
+ "ID": ch.id,
}).Debug("API channel closed.")
// delete the channel from channels map
c.channelsLock.Lock()
- delete(c.channels, ch.ID)
+ delete(c.channels, ch.id)
c.channelsLock.Unlock()
}