package mtproto

import (
	

	
	

	
	
	
)

// Invoke sends input and decodes result into output.
//
// NOTE: Assuming that call contains content message (seqno increment).
func ( *Conn) ( context.Context,  bin.Encoder,  bin.Decoder) error {
	,  := .nextMsgSeq(true)
	 := rpc.Request{
		MsgID:  ,
		SeqNo:  ,
		Input:  ,
		Output: ,
	}

	 := .log.With(
		zap.Int64("msg_id", .MsgID),
	)
	.Debug("Invoke start")
	defer .Debug("Invoke end")

	if  := .rpc.Do(, );  != nil {
		var  *badMessageError
		if errors.As(, &) && .Code == codeIncorrectServerSalt {
			// Should retry with new salt.
			.log.Debug("Setting server salt")
			// Store salt from server.
			.storeSalt(.NewSalt)
			// Reset saved salts to fetch new.
			.salts.Reset()
			.log.Info("Retrying request after basMsgErr", zap.Int64("msg_id", .MsgID))
			return .rpc.Do(, )
		}
		return errors.Wrap(, "rpcDoRequest")
	}

	return nil
}

func ( *Conn) ( rpc.Request) error {
	,  := context.WithTimeout(context.Background(),
		.getTimeout(mt.RPCDropAnswerRequestTypeID),
	)
	defer ()

	var  mt.RPCDropAnswerBox
	if  := .Invoke(, &mt.RPCDropAnswerRequest{
		ReqMsgID: .MsgID,
	}, &);  != nil {
		return 
	}

	switch .RpcDropAnswer.(type) {
	case *mt.RPCAnswerDropped, *mt.RPCAnswerDroppedRunning:
		return nil
	case *mt.RPCAnswerUnknown:
		return errors.New("answer unknown")
	default:
		return errors.Errorf("unexpected response type: %T", .RpcDropAnswer)
	}
}