public virtual IEnumerator<ITask> AttachAndSubscribeHandler(AttachAndSubscribe attach) { AttachResponse response; // Disconnect request if (attach.Body.Registration.Connection.Port == LegoNxtPort.NotConnected) { // Check if the sensor was already registered. UnregisterDevice(attach.Body.Registration.ServiceUri); response = new AttachResponse(attach.Body.Registration.Connection, attach.Body.Registration.DeviceModel); attach.ResponsePort.Post(response); yield break; } // Invalid Ports, return a fault if (attach.Body.Registration.Connection.Port == LegoNxtPort.AnyMotorPort || attach.Body.Registration.Connection.Port == LegoNxtPort.AnySensorPort || attach.Body.Registration.Connection.Port == LegoNxtPort.A || attach.Body.Registration.Connection.Port == LegoNxtPort.B || attach.Body.Registration.Connection.Port == LegoNxtPort.C || attach.Body.Registration.Connection.Port == LegoNxtPort.EncoderA || attach.Body.Registration.Connection.Port == LegoNxtPort.EncoderB || attach.Body.Registration.Connection.Port == LegoNxtPort.EncoderC) { attach.ResponsePort.Post( Fault.FromException( new ArgumentOutOfRangeException( string.Format("Invalid {0} Port: {1}", attach.Body.Registration.DeviceModel, attach.Body.Registration.Connection)))); yield break; } // Convert all inherited LegoCommand types to LegoCommands. NormalizeAttachRequest(attach.Body); string priorUri = null; string connectionKey = attach.Body.Registration.Connection.ToString(); if (_state.Runtime.Devices.ContainsKey(connectionKey)) { priorUri = _state.Runtime.Devices[connectionKey].Registration.ServiceUri; if (priorUri != attach.Body.Registration.ServiceUri) UnregisterDevice(priorUri); } _state.Runtime.Devices[connectionKey] = attach.Body; if (!string.IsNullOrEmpty(priorUri) && !priorUri.Equals(attach.Body.Registration.ServiceUri, StringComparison.InvariantCultureIgnoreCase)) { // Send Notification to prior service that it has been disconnected PortSet<DsspDefaultLookup, DsspDefaultDrop> priorServicePort = ServiceForwarder<PortSet<DsspDefaultLookup, DsspDefaultDrop>>(priorUri); priorServicePort.Post(DsspDefaultDrop.Instance); } if (_state.Runtime.Connected) { if (attach.Body.InitializationCommands != null) { foreach (LegoCommand cmd in attach.Body.InitializationCommands.Commands) { // Send Initialization Sequence. yield return Arbiter.Choice(_brickPort.SendCommand(cmd), delegate(LegoResponse ok) { }, delegate(Fault fault) { LogError(fault); }); } } } attach.Body.Registration.SubscriberUri = attach.Body.Subscriber; attach.Body.Timestamp = DateTime.Now; // Register for periodic Polling. if (attach.Body.PollingCommands != null && attach.Body.PollingCommands.Commands != null && attach.Body.PollingCommands.Commands.Count > 0) { _pollingPort.Post(new PollingEntry(attach.Body)); } response = new AttachResponse(attach.Body.Registration.Connection, attach.Body.Registration.DeviceModel); yield return Arbiter.Choice(SelectiveSubscribe(attach), delegate(SubscribeResponseType ok) { attach.ResponsePort.Post(response); }, attach.ResponsePort.Post ); yield break; }
/// <summary> /// Create a custom selective subscribe which filters on the /// service uri of the subscriber. /// </summary> /// <param name="subscribe"></param> /// <returns></returns> private PortSet<SubscribeResponseType, Fault> SelectiveSubscribe(AttachAndSubscribe subscribe) { submgr.InsertSubscription insert = new submgr.InsertSubscription(subscribe.Body); insert.Body.FilterType = submgr.FilterType.Default; //List<submgr.QueryType> query = new List<submgr.QueryType>(); //query.Add(new submgr.QueryType(subscribe.Body.Registration.ServiceUri)); //insert.Body.QueryList = query.ToArray(); _subMgrPort.Post(insert); return insert.ResponsePort; }