Fix codec fallback and generate type imports
[govpp.git] / core / connection.go
index 8b8c7b1..cfa94ee 100644 (file)
@@ -89,14 +89,13 @@ type ConnectionEvent struct {
 // Connection represents a shared memory connection to VPP via vppAdapter.
 type Connection struct {
        vppClient adapter.VppAPI // VPP binary API client
-       //statsClient adapter.StatsAPI // VPP stats API client
 
        maxAttempts int           // interval for reconnect attempts
        recInterval time.Duration // maximum number of reconnect attempts
 
        vppConnected uint32 // non-zero if the adapter is connected to VPP
 
-       codec  *codec.MsgCodec        // message codec
+       codec  MessageCodec           // message codec
        msgIDs map[string]uint16      // map of message IDs indexed by message name + CRC
        msgMap map[uint16]api.Message // map of messages indexed by message ID
 
@@ -112,6 +111,9 @@ type Connection struct {
 
        lastReplyLock sync.Mutex // lock for the last reply
        lastReply     time.Time  // time of the last received reply from VPP
+
+       msgControlPing      api.Message
+       msgControlPingReply api.Message
 }
 
 func newConnection(binapi adapter.VppAPI, attempts int, interval time.Duration) *Connection {
@@ -123,14 +125,16 @@ func newConnection(binapi adapter.VppAPI, attempts int, interval time.Duration)
        }
 
        c := &Connection{
-               vppClient:     binapi,
-               maxAttempts:   attempts,
-               recInterval:   interval,
-               codec:         &codec.MsgCodec{},
-               msgIDs:        make(map[string]uint16),
-               msgMap:        make(map[uint16]api.Message),
-               channels:      make(map[uint16]*Channel),
-               subscriptions: make(map[uint16][]*subscriptionCtx),
+               vppClient:           binapi,
+               maxAttempts:         attempts,
+               recInterval:         interval,
+               codec:               codec.DefaultCodec,
+               msgIDs:              make(map[string]uint16),
+               msgMap:              make(map[uint16]api.Message),
+               channels:            make(map[uint16]*Channel),
+               subscriptions:       make(map[uint16][]*subscriptionCtx),
+               msgControlPing:      msgControlPing,
+               msgControlPingReply: msgControlPingReply,
        }
        binapi.SetMsgCallback(c.msgCallback)
        return c
@@ -177,7 +181,9 @@ func (c *Connection) connectVPP() error {
        log.Debugf("Connected to VPP")
 
        if err := c.retrieveMessageIDs(); err != nil {
-               c.vppClient.Disconnect()
+               if err := c.vppClient.Disconnect(); err != nil {
+                       log.Debugf("disconnecting vpp client failed: %v", err)
+               }
                return fmt.Errorf("VPP is incompatible: %v", err)
        }
 
@@ -192,7 +198,6 @@ func (c *Connection) Disconnect() {
        if c == nil {
                return
        }
-
        if c.vppClient != nil {
                c.disconnectVPP()
        }
@@ -314,7 +319,7 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) {
                }
 
                // send the control ping request
-               ch.reqChan <- &vppRequest{msg: msgControlPing}
+               ch.reqChan <- &vppRequest{msg: c.msgControlPing}
 
                for {
                        // expect response within timeout period
@@ -369,7 +374,11 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) {
 }
 
 func getMsgNameWithCrc(x api.Message) string {
-       return x.GetMessageName() + "_" + x.GetCrcString()
+       return getMsgID(x.GetMessageName(), x.GetCrcString())
+}
+
+func getMsgID(name, crc string) string {
+       return name + "_" + crc
 }
 
 func getMsgFactory(msg api.Message) func() api.Message {
@@ -420,26 +429,32 @@ func (c *Connection) retrieveMessageIDs() (err error) {
 
        var n int
        for name, msg := range msgs {
+               typ := reflect.TypeOf(msg).Elem()
+               path := fmt.Sprintf("%s.%s", typ.PkgPath(), typ.Name())
+
                msgID, err := c.GetMessageID(msg)
                if err != nil {
-                       log.Debugf("retrieving msgID for %s failed: %v", name, err)
+                       if debugMsgIDs {
+                               log.Debugf("retrieving message ID for %s failed: %v", path, err)
+                       }
                        continue
                }
                n++
 
-               if c.pingReqID == 0 && msg.GetMessageName() == msgControlPing.GetMessageName() {
+               if c.pingReqID == 0 && msg.GetMessageName() == c.msgControlPing.GetMessageName() {
                        c.pingReqID = msgID
-                       msgControlPing = reflect.New(reflect.TypeOf(msg).Elem()).Interface().(api.Message)
-               } else if c.pingReplyID == 0 && msg.GetMessageName() == msgControlPingReply.GetMessageName() {
+                       c.msgControlPing = reflect.New(reflect.TypeOf(msg).Elem()).Interface().(api.Message)
+               } else if c.pingReplyID == 0 && msg.GetMessageName() == c.msgControlPingReply.GetMessageName() {
                        c.pingReplyID = msgID
-                       msgControlPingReply = reflect.New(reflect.TypeOf(msg).Elem()).Interface().(api.Message)
+                       c.msgControlPingReply = reflect.New(reflect.TypeOf(msg).Elem()).Interface().(api.Message)
                }
 
                if debugMsgIDs {
                        log.Debugf("message %q (%s) has ID: %d", name, getMsgNameWithCrc(msg), msgID)
                }
        }
-       log.Debugf("retrieved %d/%d msgIDs (took %s)", n, len(msgs), time.Since(t))
+       log.WithField("took", time.Since(t)).
+               Debugf("retrieved IDs for %d messages (registered %d)", n, len(msgs))
 
        return nil
 }