make api.Channel as interface
[govpp.git] / core / connection.go
similarity index 90%
rename from core/core.go
rename to core/connection.go
index 052eb0b..a44d0c4 100644 (file)
@@ -27,6 +27,7 @@ import (
 
        "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"
 )
 
@@ -71,13 +72,13 @@ type ConnectionEvent struct {
 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
@@ -197,8 +198,8 @@ func newConnection(vppAdapter adapter.VppAdapter) (*Connection, error) {
 
        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),
        }
@@ -268,7 +269,7 @@ func (c *Connection) connectLoop(connChan chan ConnectionEvent) {
 // 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
@@ -290,18 +291,18 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) {
 
                // 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):
@@ -349,32 +350,34 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) {
        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()
@@ -388,13 +391,13 @@ func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int)
 }
 
 // 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()
 }