public override async Task <MessageEntry> CallSetProperty(MessageEntry m)
        {
            string         ename = m.MemberName;
            MessageElement me    = m.FindElement("value");
            MessageEntry   mr    = new MessageEntry(MessageEntryType.PropertySetRes, ename);

            switch (ename)
            {
            case "d1":
            {
                await obj.set_d1((MessageElementUtil.UnpackScalar <double>(me)));

                break;
            }

            case "d2":
            {
                await obj.set_d2(MessageElementUtil.UnpackArray <double>(me));

                break;
            }

            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(mr);
        }
Beispiel #2
0
        public async Task <string> RequestObjectLock(object obj, RobotRaconteurObjectLockFlags flags, CancellationToken cancel = default(CancellationToken))
        {
            if (!(obj is ServiceStub))
            {
                throw new InvalidOperationException("Can only lock object opened through Robot Raconteur");
            }
            ServiceStub s = (ServiceStub)obj;

            string command = "";

            if (flags == RobotRaconteurObjectLockFlags.USER_LOCK)
            {
                command = "RequestObjectLock";
            }
            else if (flags == RobotRaconteurObjectLockFlags.CLIENT_LOCK)
            {
                command = "RequestClientObjectLock";
            }
            else
            {
                throw new InvalidOperationException("Unknown flags");
            }

            MessageEntry m = new MessageEntry(MessageEntryType.ClientSessionOpReq, command);

            m.ServicePath = s.RRServicePath;

            MessageEntry ret = await ProcessRequest(m, cancel);

            return(ret.FindElement("return").CastData <string>());
        }
        public async Task <double> add_val(double v, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry rr_m = new MessageEntry(MessageEntryType.FunctionCallReq, "add_val");

            MessageElementUtil.AddMessageElement(rr_m, MessageElementUtil.PackScalar <double>("v", v));
            MessageEntry rr_me = await ProcessRequest(rr_m, cancel);

            return(MessageElementUtil.UnpackScalar <double>(rr_me.FindElement("return")));
        }
        public async Task <double[]> get_d2(CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry m  = new MessageEntry(MessageEntryType.PropertyGetReq, "d2");
            MessageEntry mr = await ProcessRequest(m, cancel);

            MessageElement me = mr.FindElement("value");

            return(MessageElementUtil.UnpackArray <double>(me));
        }
        public async Task <Dictionary <int, ServiceInfo> > GetLocalNodeServices(CancellationToken rr_cancel = default(CancellationToken))
        {
            MessageEntry rr_mm = new MessageEntry(MessageEntryType.FunctionCallReq, "GetLocalNodeServices");
            MessageEntry rr_mr = await ProcessRequest(rr_mm, rr_cancel);

            MessageElement rr_me = rr_mr.FindElement("return");

            return((Dictionary <int, ServiceInfo>)RRContext.UnpackMapType <int, ServiceInfo>(rr_me.Data));
        }
        public async Task <double> func3(double d1, double d2, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry rr_m = new MessageEntry(MessageEntryType.FunctionCallReq, "func3");

            MessageElementUtil.AddMessageElement(rr_m, MessageElementUtil.PackScalar <double>("d1", d1));
            MessageElementUtil.AddMessageElement(rr_m, MessageElementUtil.PackScalar <double>("d2", d2));
            MessageEntry rr_me = await ProcessRequest(rr_m, cancel);

            return(MessageElementUtil.UnpackScalar <double>(rr_me.FindElement("return")));
        }
Beispiel #7
0
        public async Task <uint> CheckServiceCapability(string name, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry m = new MessageEntry(MessageEntryType.ServiceCheckCapabilityReq, name);

            m.ServicePath = m_ServiceName;
            MessageEntry ret = await ProcessRequest(m, cancel);

            uint res = ret.FindElement("return").CastData <uint>();

            return(res);
        }
        public override async Task <MessageEntry> CallSetProperty(MessageEntry m)
        {
            string         ename = m.MemberName;
            MessageElement me    = m.FindElement("value");
            MessageEntry   mr    = new MessageEntry(MessageEntryType.PropertySetRes, ename);

            switch (ename)
            {
            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(mr);
        }
        protected override async Task <MessageEntry> CallbackCall(MessageEntry rr_m)
        {
            string       rr_ename = rr_m.MemberName;
            MessageEntry rr_mr    = new MessageEntry(MessageEntryType.CallbackCallRet, rr_ename);

            rr_mr.ServicePath = rr_m.ServicePath;
            rr_mr.RequestID   = rr_m.RequestID;
            switch (rr_ename)
            {
            case "cb2": {
                double d1 = (MessageElementUtil.UnpackScalar <double>(rr_m.FindElement("d1")));
                double d2 = (MessageElementUtil.UnpackScalar <double>(rr_m.FindElement("d2")));
                await this.cb2.Function(d1, d2, default(CancellationToken));

                MessageElementUtil.AddMessageElement(rr_mr, MessageElementUtil.PackScalar <int>("return", 0));
                break;
            }

            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(rr_mr);
        }
Beispiel #10
0
        public async Task <string> ReleaseObjectLock(object obj, CancellationToken cancel = default(CancellationToken))
        {
            if (!(obj is ServiceStub))
            {
                throw new InvalidOperationException("Can only unlock object opened through Robot Raconteur");
            }
            ServiceStub s = (ServiceStub)obj;

            MessageEntry m = new MessageEntry(MessageEntryType.ClientSessionOpReq, "ReleaseObjectLock");

            m.ServicePath = s.RRServicePath;

            MessageEntry ret = await ProcessRequest(m, cancel);

            return(ret.FindElement("return").CastData <string>());
        }
Beispiel #11
0
        public async Task <string> LogoutUser(CancellationToken cancel = default(CancellationToken))
        {
            if (!UserAuthenticated)
            {
                throw new AuthenticationException("User is not authenticated");
            }

            m_UserAuthenticated     = false;
            m_AuthenticatedUsername = null;

            MessageEntry m = new MessageEntry(MessageEntryType.ClientSessionOpReq, "LogoutUser");

            m.ServicePath = ServiceName;
            m.AddElement("username", AuthenticatedUsername);
            MessageEntry ret = await ProcessRequest(m, cancel);

            return(ret.FindElement("return").CastData <string>());
        }
        public override object GetCallbackFunction(uint rr_endpoint, string rr_membername)
        {
            switch (rr_membername)
            {
            case "cb2": {
                return(new Func <double, double, CancellationToken, Task>(async delegate(double d1, double d2, CancellationToken rr_cancel) {
                        MessageEntry rr_mm = new MessageEntry(MessageEntryType.CallbackCallReq, "cb2");
                        rr_mm.ServicePath = m_ServicePath;
                        MessageElementUtil.AddMessageElement(rr_mm, MessageElementUtil.PackScalar <double>("d1", d1));
                        MessageElementUtil.AddMessageElement(rr_mm, MessageElementUtil.PackScalar <double>("d2", d2));
                        MessageEntry rr_mr = await RRContext.ProcessCallbackRequest(rr_mm, rr_endpoint, rr_cancel);
                        MessageElement rr_me = rr_mr.FindElement("return");
                    }));
            }

            default:
                break;
            }
            throw new MemberNotFoundException("Member not found");
        }
Beispiel #13
0
        public async Task <string> AuthenticateUser(string username, object credentials, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry m = new MessageEntry(MessageEntryType.ClientSessionOpReq, "AuthenticateUser");

            m.ServicePath = ServiceName;
            m.AddElement("username", username);
            if (credentials is Dictionary <string, object> )
            {
                m.AddElement("credentials", PackMapType <string, object>(credentials));
            }
            else if (credentials is MessageElement)
            {
                MessageElement mcredentials = (MessageElement)credentials;
                mcredentials.ElementName = "credentials";
                m.AddElement(mcredentials);
            }
            MessageEntry ret = await ProcessRequest(m, cancel);

            m_AuthenticatedUsername = username;
            m_UserAuthenticated     = true;
            return(ret.FindElement("return").CastData <string>());
        }
Beispiel #14
0
        public override async Task <PipeEndpoint> Connect(int index, CancellationToken cancel = default(CancellationToken))
        {
            object connecting_key = new object();

            connecting.Add(Tuple.Create(index, connecting_key));
            int rindex = -1;

            try
            {
                MessageEntry m = new MessageEntry(MessageEntryType.PipeConnectReq, MemberName);
                m.AddElement("index", index);
                MessageEntry ret = await stub.ProcessRequest(m, cancel);

                rindex = (ret.FindElement("index").CastData <int[]>())[0];

                PipeEndpoint e;
                if (early_endpoints.ContainsKey(rindex))
                {
                    e = early_endpoints[rindex];
                    early_endpoints.Remove(rindex);
                }
                else
                {
                    e = new PipeEndpoint(this, rindex);
                }
                pipeendpoints.Add(rindex, e);
                return(e);
            }
            finally
            {
                connecting.RemoveAll(x => Object.ReferenceEquals(x.Item2, connecting_key));
                if (connecting.Count == 0)
                {
                    early_endpoints.Clear();
                }
            }
        }
Beispiel #15
0
        public async Task MonitorExit(RobotRaconteurNode.MonitorLock lock_, CancellationToken cancel = default(CancellationToken))
        {
            try
            {
                MessageEntry m = new MessageEntry(MessageEntryType.ClientSessionOpReq, "MonitorExit");
                m.ServicePath = lock_.stub.RRServicePath;

                MessageEntry ret = await ProcessRequest(m, cancel);

                string retcode = ret.FindElement("return").CastData <string>();
                if (retcode != "OK")
                {
                    throw new ProtocolException("Unknown return code");
                }
            }
            finally
            {
                try
                {
                    lock_.lock_.Dispose();
                }
                catch { }
            }
        }
Beispiel #16
0
        public override void PipePacketReceived(MessageEntry m, Endpoint e = null)
        {
            if (m.EntryType == MessageEntryType.PipeClosed)
            {
                try
                {
                    int index = (m.FindElement("index").CastData <int[]>())[0];
                    pipeendpoints[index].RemoteClose();
                }
                catch { };
            }
            else if (m.EntryType == MessageEntryType.PipePacket)
            {
                List <MessageElement> ack = new List <MessageElement>();
                foreach (MessageElement me in m.elements)
                {
                    try
                    {
                        int  index = Int32.Parse(me.ElementName);
                        uint pnum;

                        PipeEndpoint p = null;
                        if (pipeendpoints.ContainsKey(index))
                        {
                            p = pipeendpoints[index];
                        }
                        else
                        {
                            if (early_endpoints.ContainsKey(index))
                            {
                                p = early_endpoints[index];
                            }
                            else
                            if (connecting.Count > 0)
                            {
                                if (connecting.Any(x => x.Item1 == -1 || x.Item1 == index))
                                {
                                    p = new PipeEndpoint(this, index);
                                    early_endpoints.Add(index, p);
                                }
                            }
                        }

                        if (p == null)
                        {
                            continue;
                        }
                        if (DispatchPacket(me, p, out pnum))
                        {
                            ack.Add(new MessageElement(me.ElementName, new uint[] { pnum }));
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
                try
                {
                    if (ack.Count > 0)
                    {
                        MessageEntry mack = new MessageEntry(MessageEntryType.PipePacketRet, m.MemberName);
                        mack.elements = ack;
                        stub.SendPipeMessage(mack, default(CancellationToken)).IgnoreResult();
                    }
                }
                catch { }
            }
            else if (m.EntryType == MessageEntryType.PipePacketRet)
            {
                try
                {
                    foreach (MessageElement me in m.elements)
                    {
                        int index = Int32.Parse(me.ElementName);
                        DispatchPacketAck(me, pipeendpoints[index]);
                    }
                }
                catch { }
            }
        }
Beispiel #17
0
        public async Task <object> ConnectService(Transport c, string url, string username = null, object credentials = null, string objecttype = null, CancellationToken cancel = default(CancellationToken))
        {
            this.connecturl       = url;
            this.connecttransport = c;
            var u = TransportUtil.ParseConnectionUrl(url);

            m_RemoteNodeID = u.nodeid;

            m_RemoteNodeName = u.nodename;
            m_ServiceName    = u.service;

            //ProgramName = ProgramName1;

            /* try
             * {*/
            //if (RobotRaconteurService.s.transports[c] == null) return null;
            if (!c.CanConnectService(url))
            {
                throw new ServiceException("Invalid transport");
            }

            TransportConnection = await c.CreateTransportConnection(url, this, cancel);

            m_Connected = true;
            try
            {
                transport        = c.TransportID;
                m_RemoteEndpoint = 0;

                ServiceDefinition[] d = await PullServiceDefinitionAndImports(null, cancel : cancel);

                lock (pulled_service_defs)
                {
                    foreach (var d2 in d)
                    {
                        if (!pulled_service_defs.ContainsKey(d2.Name))
                        {
                            pulled_service_defs.Add(d2.Name, d2);
                        }
                    }
                }

                if (!UsePulledServiceTypes)
                {
                    m_ServiceDef = node.GetServiceType(d[0].Name);
                }
                else
                {
                    var f = DynamicServiceFactory_.CreateServiceFactories(d.Select(x => x.ToString()).ToArray(), this);
                    lock (pulled_service_defs)
                    {
                        foreach (var f2 in f)
                        {
                            if (!pulled_service_types.ContainsKey(f2.GetServiceName()))
                            {
                                pulled_service_types.Add(f2.GetServiceName(), f2);
                            }
                        }
                    }
                    m_ServiceDef = GetPulledServiceType(d[0].Name);
                }

                MessageEntry e = new MessageEntry(MessageEntryType.ObjectTypeName, "");
                //e.AddElement("servicepath", ServiceName);
                e.ServicePath = ServiceName;

                MessageEntry ret = await ProcessRequest(e, cancel);

                if (ret.Error != MessageErrorType.None)
                {
                    return(null);
                }
                string type = ret.FindElement("objecttype").CastData <string>();
                if (type == "")
                {
                    return(new ObjectNotFoundException("Could not find object type"));
                }
                ;


                if (objecttype != null)
                {
                    VerifyObjectImplements(type, objecttype);
                    type = objecttype;
                    await PullServiceDefinitionAndImports(ServiceDefinitionUtil.SplitQualifiedName(type).Item2, cancel);
                }


                MessageEntry e2 = new MessageEntry();
                e2.ServicePath = ServiceName;
                e2.MemberName  = "registerclient";
                e2.EntryType   = MessageEntryType.ConnectClient;
                await ProcessRequest(e2, cancel);

                if (username != null)
                {
                    await AuthenticateUser(username, credentials, cancel);
                }

                ServiceStub stub = ServiceDef.CreateStub(type, ServiceName, this);
                stubs.Add(ServiceName, stub);
                Task noop = PeriodicTask.Run(PeriodicCleanupTask, TimeSpan.FromSeconds(5), cancel_source.Token).IgnoreResult();

                return(stub);
            }
            catch (Exception e)
            {
                try
                {
                    TransportConnection.Close();
                }
                catch { }

                m_Connected = false;
                throw e;
            }


            /*}
             * catch {
             *  return null;
             * }*/
        }
Beispiel #18
0
        public async Task <object> FindObjRef(string path, string objecttype, CancellationToken cancel)
        {
            lock (stubs)
            {
                if (stubs.Keys.Contains(path))
                {
                    return(stubs[path]);
                }
            }

            MessageEntry e = new MessageEntry(MessageEntryType.ObjectTypeName, "");

            //MessageElement m = e.AddElement("ObjectPath", path);
            e.ServicePath = path;
            MessageEntry ret = await ProcessRequest(e, cancel);

            string objecttype2 = ret.FindElement("objecttype").CastData <string>();

            if (objecttype2 == "")
            {
                throw new ObjectNotFoundException("Object type was not returned.");
            }

            string objectdef = ServiceDefinitionUtil.SplitQualifiedName(objecttype2).Item1;

            if (UsePulledServiceTypes)
            {
                bool pull = false;
                lock (pulled_service_types)
                {
                    if (!pulled_service_types.ContainsKey(objectdef))
                    {
                        pull = true;
                    }
                }
                if (pull)
                {
                    ServiceDefinition[] d = await PullServiceDefinitionAndImports(null, cancel : cancel);

                    lock (pulled_service_defs)
                    {
                        foreach (var d2 in d)
                        {
                            if (!pulled_service_defs.ContainsKey(d2.Name))
                            {
                                pulled_service_defs.Add(d2.Name, d2);
                            }
                        }
                    }

                    var f = DynamicServiceFactory_.CreateServiceFactories(d.Select(x => x.ToString()).ToArray(), this);
                    lock (pulled_service_defs)
                    {
                        foreach (var f2 in f)
                        {
                            if (!pulled_service_types.ContainsKey(f2.GetServiceName()))
                            {
                                pulled_service_types.Add(f2.GetServiceName(), f2);
                            }
                        }
                    }
                }
            }

            if (objecttype != null)
            {
                VerifyObjectImplements(objecttype2, objecttype);
                objecttype2 = objecttype;
            }

            var stub = ServiceDef.CreateStub(objecttype2, path, this);

            lock (stubs)
            {
                if (!stubs.Keys.Contains(path))
                {
                    stubs[path] = stub;
                    return(stub);
                }
                else
                {
                    return(stubs[path]);
                }
            }
        }
        public static Exception MessageEntryToException(MessageEntry entry)
        {
            var error_code  = entry.Error;
            var errorname   = entry.FindElement("errorname").CastData <string>();
            var errorstring = entry.FindElement("errorstring").CastData <string>();

            switch (error_code)
            {
            case MessageErrorType.RemoteError:
                RobotRaconteurException e1 = new RobotRaconteurRemoteException(errorname, errorstring);
                return(e1);

            case MessageErrorType.ConnectionError:
                return(new ConnectionException(errorstring));

            case MessageErrorType.ProtocolError:
                return(new ProtocolException(errorstring));

            case MessageErrorType.ServiceNotFound:
                return(new ServiceNotFoundException(errorstring));

            case MessageErrorType.ObjectNotFound:
                return(new ObjectNotFoundException(errorstring));

            case MessageErrorType.InvalidEndpoint:
                return(new InvalidEndpointException(errorstring));

            case MessageErrorType.EndpointCommunicationFatalError:
                return(new EndpointCommunicationFatalException(errorstring));

            case MessageErrorType.NodeNotFound:
                return(new NodeNotFoundException(errorstring));

            case MessageErrorType.ServiceError:
                return(new ServiceException(errorstring));

            case MessageErrorType.MemberNotFound:
                return(new MemberNotFoundException(errorstring));

            case MessageErrorType.MemberFormatMismatch:
                return(new MemberFormatMismatchException(errorstring));

            case MessageErrorType.DataTypeMismatch:
                return(new DataTypeMismatchException(errorstring));

            case MessageErrorType.DataTypeError:
                return(new DataTypeException(errorstring));

            case MessageErrorType.DataSerializationError:
                return(new DataSerializationException(errorstring));

            case MessageErrorType.MessageEntryNotFound:
                return(new MessageEntryNotFoundException(errorstring));

            case MessageErrorType.MessageElementNotFound:
                return(new MessageElementNotFoundException(errorstring));

            case MessageErrorType.UnknownError:
                return(new UnknownException(errorname, errorstring));

            case MessageErrorType.InvalidOperation:
                return(new InvalidOperationException(errorstring));

            case MessageErrorType.InvalidArgument:
                return(new ArgumentException(errorstring));

            case MessageErrorType.OperationFailed:
                return(new OperationFailedException(errorstring));

            case MessageErrorType.NullValue:
                return(new NullReferenceException(errorstring));

            case MessageErrorType.InternalError:
                return(new InternalErrorException(errorstring));

            case MessageErrorType.SystemResourcePermissionDenied:
                return(new SystemResourcePermissionDeniedException(errorstring));

            case MessageErrorType.OutOfSystemResource:
                return(new OutOfSystemResourceException(errorstring));

            case MessageErrorType.SystemResourceError:
                return(new SystemResourceException(errorstring));

            case MessageErrorType.ResourceNotFound:
                return(new ResourceNotFoundException(errorstring));

            case MessageErrorType.IOError:
                return(new System.IO.IOException(errorstring));

            case MessageErrorType.BufferLimitViolation:
                return(new BufferLimitViolationException(errorstring));

            case MessageErrorType.ServiceDefinitionError:
                return(new ServiceDefinitionException(errorstring));

            case MessageErrorType.OutOfRange:
                return(new ArgumentOutOfRangeException(errorstring));

            case MessageErrorType.KeyNotFound:
                return(new KeyNotFoundException(errorstring));

            case MessageErrorType.RequestTimeout:
                return(new RequestTimeoutException(errorstring));

            case MessageErrorType.ReadOnlyMember:
                return(new ReadOnlyMemberException(errorstring));

            case MessageErrorType.WriteOnlyMember:
                return(new WriteOnlyMemberException(errorstring));

            case MessageErrorType.NotImplementedError:
                return(new NotImplementedException(errorstring));

            case MessageErrorType.MemberBusy:
                return(new MemberBusyException(errorstring));

            case MessageErrorType.ValueNotSet:
                return(new ValueNotSetException(errorstring));

            case MessageErrorType.AuthenticationError:
                return(new AuthenticationException(errorstring));

            case MessageErrorType.ObjectLockedError:
                return(new ObjectLockedException(errorstring));

            case MessageErrorType.PermissionDenied:
                return(new PermissionDeniedException(errorstring));

            case MessageErrorType.AbortOperation:
                return(new AbortOperationException(errorstring));

            case MessageErrorType.OperationAborted:
                return(new OperationAbortedException(errorstring));

            case MessageErrorType.StopIteration:
                return(new StopIterationException(errorstring));
            }

            return(new RobotRaconteurException(error_code, errorname, errorstring));
        }
Beispiel #20
0
        public async Task <RobotRaconteurNode.MonitorLock> MonitorEnter(object obj, int timeout, CancellationToken cancel = default(CancellationToken))
        {
            bool        iserror = true;
            IDisposable lock_   = null;

            try
            {
                if (!(obj is ServiceStub))
                {
                    throw new InvalidOperationException("Can only unlock object opened through Robot Raconteur");
                }
                ServiceStub s = (ServiceStub)obj;
                lock_ = await s.rr_async_mutex.Lock();

                bool         keep_trying = true;
                MessageEntry m           = new MessageEntry(MessageEntryType.ClientSessionOpReq, "MonitorEnter");
                m.ServicePath = s.RRServicePath;
                m.AddElement("timeout", timeout);

                MessageEntry ret = await ProcessRequest(m, cancel);

                string retcode = ret.FindElement("return").CastData <string>();

                if (retcode == "OK")
                {
                    iserror = false;
                    return(new RobotRaconteurNode.MonitorLock
                    {
                        lock_ = lock_,
                        stub = s
                    });
                }
                if (retcode == "Continue")
                {
                    while (keep_trying)
                    {
                        MessageEntry m1 = new MessageEntry(MessageEntryType.ClientSessionOpReq, "MonitorContinueEnter");
                        m1.ServicePath = s.RRServicePath;

                        MessageEntry ret1 = await ProcessRequest(m1, cancel);

                        string retcode1 = ret1.FindElement("return").CastData <string>();
                        if (retcode1 == "OK")
                        {
                            iserror = false;
                            return(new RobotRaconteurNode.MonitorLock
                            {
                                lock_ = lock_,
                                stub = s
                            });
                        }
                        if (retcode1 != "Continue")
                        {
                            throw new ProtocolException("Unknown return code");
                        }
                    }
                }
                else
                {
                    throw new ProtocolException("Unknown return code");
                }
            }
            finally
            {
                if (iserror)
                {
                    if (lock_ != null)
                    {
                        try
                        {
                            lock_.Dispose();
                        }
                        catch { }
                    }
                    //Monitor.Exit(obj);
                }
            }

            throw new ProtocolException("Unknown return code");
        }
Beispiel #21
0
        public Task <MessageEntry> PipeCommand(MessageEntry m, Endpoint e)
        {
            lock (pipeendpointlock)
            {
                switch (m.EntryType)
                {
                case MessageEntryType.PipeConnectReq:
                {
                    if (!pipeendpoints.Keys.Contains(e.LocalEndpoint))
                    {
                        pipeendpoints.Add(e.LocalEndpoint, new Dictionary <int, PipeEndpoint>());
                    }

                    Dictionary <int, PipeEndpoint> ep = pipeendpoints[e.LocalEndpoint];

                    int index = (m.FindElement("index").CastData <int[]>())[0];
                    if (index == -1)
                    {
                        index = (ep.Count == 0) ? 1 : (ep.Keys.Max() + 1);
                    }

                    if (ep.Keys.Contains(index))
                    {
                        throw new Exception("Pipe endpoint index in use");
                    }

                    PipeEndpoint p = new PipeEndpoint(this, index, e);
                    ep.Add(index, p);
                    try
                    {
                        if (callback != null)
                        {
                            callback(p);
                        }
                    }
                    catch { }

                    MessageEntry ret = new MessageEntry(MessageEntryType.PipeConnectRet, MemberName);
                    ret.AddElement("index", index);
                    return(Task.FromResult(ret));
                }

                case MessageEntryType.PipeDisconnectReq:
                {
                    if (!pipeendpoints.Keys.Contains(e.LocalEndpoint))
                    {
                        throw new Exception("Invalid pipe");
                    }
                    Dictionary <int, PipeEndpoint> ep = pipeendpoints[e.LocalEndpoint];

                    int index = (m.FindElement("index").CastData <int[]>())[0];
                    if (!ep.Keys.Contains(index))
                    {
                        throw new Exception("Invalid pipe");
                    }


                    ep.Remove(index);

                    return(Task.FromResult(new MessageEntry(MessageEntryType.PipeDisconnectReq, MemberName)));
                }

                default:
                    throw new Exception("Invalid Command");
                }
            }
        }