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); }
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"))); }
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); }
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>()); }
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"); }
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>()); }
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(); } } }
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 { } } }
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 { } } }
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; * }*/ }
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)); }
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"); }
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"); } } }