public override async Task <MessageEntry> CallFunction(MessageEntry rr_m)
        {
            string       rr_ename = rr_m.MemberName;
            MessageEntry rr_mr    = new MessageEntry(MessageEntryType.FunctionCallRes, rr_ename);

            switch (rr_ename)
            {
            case "GetLocalNodeServices": {
                object rr_ret = await obj.GetLocalNodeServices(default(CancellationToken));

                rr_mr.AddElement(new MessageElement("return", RRContext.PackMapType <int, ServiceInfo>(rr_ret)));
                break;
            }

            case "GetRoutedNodes": {
                object rr_ret = await obj.GetRoutedNodes(default(CancellationToken));

                rr_mr.AddElement(new MessageElement("return", RRContext.PackMapType <int, NodeInfo>(rr_ret)));
                break;
            }

            case "GetDetectedNodes": {
                object rr_ret = await obj.GetDetectedNodes(default(CancellationToken));

                rr_mr.AddElement(new MessageElement("return", RRContext.PackMapType <int, NodeInfo>(rr_ret)));
                break;
            }

            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(rr_mr);
        }
        public override async Task <MessageEntry> CallGetProperty(MessageEntry m)
        {
            string       ename = m.MemberName;
            MessageEntry mr    = new MessageEntry(MessageEntryType.PropertyGetRes, ename);

            switch (ename)
            {
            case "d1":
            {
                double ret = await obj.get_d1();

                mr.AddElement(MessageElementUtil.PackScalar <double>("value", ret));
                break;
            }

            case "d2":
            {
                double[] ret = await obj.get_d2();

                mr.AddElement(MessageElementUtil.PackArray <double>("value", ret));
                break;
            }

            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(mr);
        }
コード例 #3
0
        public async Task Close(CancellationToken cancel = default(CancellationToken))
        {
            cancel_source.Cancel();

            try
            {
                MessageEntry e = new MessageEntry(MessageEntryType.DisconnectClient, "");
                e.AddElement("servicename", ServiceName);
                await ProcessRequest(e, cancel);
            }
            catch (Exception)
            {
            }


            stubs.Clear();
            m_Connected = false;
            node.DeleteEndpoint(this);

            try
            {
                if (ClientServiceListener != null)
                {
                    ClientServiceListener(this, ClientServiceListenerEventType.ClientClosed, null);
                }
            }
            catch { }
        }
コード例 #4
0
        protected async Task <ServiceDefinition> PullServiceDefinition(string servicetype, CancellationToken cancel)
        {
            var e3 = new MessageEntry(MessageEntryType.GetServiceDesc, "");

            e3.ServicePath = m_ServiceName;
            if (servicetype != null)
            {
                e3.AddElement("ServiceType", servicetype);
            }

            var res = await ProcessRequest(e3, cancel);

            var def = res.FindElement("servicedef").CastData <string>();

            if (def == "")
            {
                throw new ServiceNotFoundException("Could not find service definition");
            }
            var d = new ServiceDefinition();

            d.FromString(def);

            if (servicetype == null)
            {
                if (res.elements.Count(x => x.ElementName == "attributes") != 0)
                {
                    lock (this)
                    {
                        Attributes = (Dictionary <string, object>)node.UnpackMapType <string, object>(res.FindElement("attributes").CastData <MessageElementMap <string> >(), null);
                    }
                }
            }

            return(d);
        }
コード例 #5
0
        protected override async Task Close(PipeEndpoint e, Endpoint ee = null, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry m = new MessageEntry(MessageEntryType.PipeDisconnectReq, MemberName);

            m.AddElement("index", e.Index);
            MessageEntry ret = await stub.ProcessRequest(m, cancel);
        }
コード例 #6
0
        protected override async Task SendPipePacket(T data, int index, uint packetnumber, bool requestack, Endpoint e = null, CancellationToken cancel = default(CancellationToken))
        {
            MessageElement me = PackPacket(data, index, packetnumber, requestack);
            MessageEntry   m  = new MessageEntry(MessageEntryType.PipePacket, MemberName);

            m.AddElement(me);
            await stub.SendPipeMessage(m, cancel);
        }
コード例 #7
0
        protected override async Task Close(PipeEndpoint e, Endpoint ee, CancellationToken cancel = default(CancellationToken))
        {
            MessageEntry m = new MessageEntry(MessageEntryType.PipeClosed, MemberName);

            m.AddElement("index", e.Index);
            await skel.SendPipeMessage(m, ee, cancel);

            DeleteEndpoint(e);
        }
コード例 #8
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>());
        }
コード例 #9
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>());
        }
コード例 #10
0
        protected override async Task SendPipePacket(T data, int index, uint packetnumber, bool requestack, Endpoint e = null, CancellationToken cancel = default(CancellationToken))
        {
            if (!pipeendpoints.ContainsKey(e.LocalEndpoint))
            {
                throw new Exception("Pipe has been disconnect");
            }
            if (!pipeendpoints[e.LocalEndpoint].ContainsKey(index))
            {
                throw new Exception("Pipe has been disconnected");
            }

            MessageElement me = PackPacket(data, index, packetnumber, requestack);
            MessageEntry   m  = new MessageEntry(MessageEntryType.PipePacket, MemberName);

            m.AddElement(me);

            await skel.SendPipeMessage(m, e, cancel);
        }
コード例 #11
0
        protected virtual void CheckEndpointCapabilityMessage(Message m)
        {
            uint         capability = 0;
            MessageEntry e;

            Message ret = new Message();

            ret.header = new MessageHeader();
            ret.header.ReceiverNodeName = m.header.SenderNodeName;
            ret.header.SenderNodeName   = node.NodeName;
            ret.header.ReceiverNodeID   = m.header.SenderNodeID;
            ret.header.ReceiverEndpoint = m.header.SenderEndpoint;
            ret.header.SenderEndpoint   = m.header.ReceiverEndpoint;
            ret.header.SenderNodeID     = node.NodeID;


            try
            {
                if (m.entries.Count == 0)
                {
                    throw new InvalidOperationException();
                }

                e = m.entries[0];

                MessageEntry eret = ret.AddEntry(MessageEntryType.EndpointCheckCapabilityRet, m.entries[0].MemberName);
                eret.RequestID   = e.RequestID;
                eret.ServicePath = e.ServicePath;

                if (e.EntryType != MessageEntryType.EndpointCheckCapability)
                {
                    throw new InvalidOperationException();
                }
                string name = e.MemberName;
                capability = EndpointCapability(name);
                eret.AddElement("return", capability);
            }
            catch
            {
            }

            SendMessage(ret, default(CancellationToken)).IgnoreResult();
        }
        public override async Task <MessageEntry> CallFunction(MessageEntry rr_m)
        {
            string       rr_ename = rr_m.MemberName;
            MessageEntry rr_mr    = new MessageEntry(MessageEntryType.FunctionCallRes, rr_ename);

            switch (rr_ename)
            {
            case "add_val":
            {
                double v      = (MessageElementUtil.UnpackScalar <double>(MessageElementUtil.FindElement(rr_m, "v")));
                double rr_ret = await this.obj.add_val(v, default(CancellationToken));

                rr_mr.AddElement(MessageElementUtil.PackScalar <double>("return", rr_ret));
                break;
            }

            default:
                throw new MemberNotFoundException("Member not found");
            }
            return(rr_mr);
        }
コード例 #13
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();
                }
            }
        }
コード例 #14
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");
        }
コード例 #15
0
        public static void ExceptionToMessageEntry(Exception exception, MessageEntry entry)
        {
            if (exception is InvalidOperationException)
            {
                entry.Error = MessageErrorType.InvalidOperation;
                entry.AddElement("errorname", "RobotRaconteur.InvalidOperation");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is ArgumentException)
            {
                entry.Error = MessageErrorType.InvalidArgument;
                entry.AddElement("errorname", "RobotRaconteur.InvalidArgument");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is NullReferenceException)
            {
                entry.Error = MessageErrorType.NullValue;
                entry.AddElement("errorname", "RobotRaconteur.NullValue");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is NotImplementedException)
            {
                entry.Error = MessageErrorType.NotImplementedError;
                entry.AddElement("errorname", "RobotRaconteur.NotImplementedError");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is ArgumentOutOfRangeException)
            {
                entry.Error = MessageErrorType.OutOfRange;
                entry.AddElement("errorname", "RobotRaconteur.OutOfRange");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is KeyNotFoundException)
            {
                entry.Error = MessageErrorType.KeyNotFound;
                entry.AddElement("errorname", "RobotRaconteur.KeyNotFound");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is System.IO.IOException)
            {
                entry.Error = MessageErrorType.IOError;
                entry.AddElement("errorname", "RobotRaconteur.IOError");
                entry.AddElement("errorstring", exception.Message);
                return;
            }

            if (exception is RobotRaconteurException)
            {
                RobotRaconteurException r = (RobotRaconteurException)exception;
                entry.Error = r.ErrorCode;
                entry.AddElement("errorname", r.Error);
                entry.AddElement("errorstring", r.Message);
            }
            else
            {
                entry.Error = MessageErrorType.RemoteError;
                entry.AddElement("errorname", exception.GetType().ToString());
                entry.AddElement("errorstring", exception.Message);
            }
        }
コード例 #16
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");
                }
            }
        }