// handleCallMessage handles a received call message. It mutates the // capability table of its parameter. The caller holds onto c.mu. func (c *Conn) handleCallMessage(m rpccapnp.Message) error { mcall, err := m.Call() if err != nil { return err } mt, err := mcall.Target() if err != nil { return err } if mt.Which() != rpccapnp.MessageTarget_Which_importedCap && mt.Which() != rpccapnp.MessageTarget_Which_promisedAnswer { um := newUnimplementedMessage(nil, m) return c.sendMessage(um) } mparams, err := mcall.Params() if err != nil { return err } if err := c.populateMessageCapTable(mparams); err == errUnimplemented { um := newUnimplementedMessage(nil, m) return c.sendMessage(um) } else if err != nil { c.abort(err) return err } ctx, cancel := c.newContext() id := answerID(mcall.QuestionId()) a := c.insertAnswer(id, cancel) if a == nil { // Question ID reused, error out. c.abort(errQuestionReused) return errQuestionReused } meth := capnp.Method{ InterfaceID: mcall.InterfaceId(), MethodID: mcall.MethodId(), } paramContent, err := mparams.ContentPtr() if err != nil { return err } cl := &capnp.Call{ Ctx: ctx, Method: meth, Params: paramContent.Struct(), } if err := c.routeCallMessage(a, mt, cl); err != nil { return a.reject(err) } return nil }