/// <summary> /// Service Start /// </summary> protected override void Start() { InitializeState(); // Set up the reliable port using DSS forwarder to ensure exception and timeout conversion to fault. _reliableMainPort = ServiceForwarder<NxtBrickOperations>(this.ServiceInfo.Service); // Make the service visible immediately DirectoryInsert(); // Handle some handlers all the time -- even during initialization and exclusive handlers. Activate<ITask>( Arbiter.ReceiveWithIterator<Get>(true, _internalMainPort, GetHandler), Arbiter.Receive<HttpGet>(true, _internalMainPort, HttpGetHandler), Arbiter.Receive<DsspDefaultLookup>(true, _internalMainPort, base.DefaultLookupHandler), Arbiter.ReceiveWithIterator<LegoSensorUpdate>(true, _internalMainPort, LegoSensorUpdateHandler) ); // Start initializing the communications service DsspResponsePort<CreateResponse> nxtCommunicationResponse = CreateNxtCommunicationService(); // Activate on all operations. // Operations which require a connection to the hardware will throw a fault. Interleave initializationInterleave = new Interleave( new TeardownReceiverGroup( Arbiter.ReceiveWithIterator<CreateResponse>(false, nxtCommunicationResponse, ServiceInitialization), Arbiter.ReceiveWithIterator<DsspDefaultDrop>(false, _internalMainPort, DropHandler) ), new ExclusiveReceiverGroup( Arbiter.ReceiveWithIterator<AttachAndSubscribe>(true, _internalMainPort, AttachAndSubscribeHandler), Arbiter.ReceiveWithIterator<ReserveDevicePort>(true, _internalMainPort, ReserveDevicePortHandler), Arbiter.ReceiveWithIterator<Subscribe>(true, _internalMainPort, SubscribeHandler), Arbiter.ReceiveWithIterator<Detach>(true, _internalMainPort, DetachHandler), Arbiter.ReceiveWithIterator <AdjustPollingFrequency>(true, _internalMainPort, AdjustPollingFrequencyHandler) ), new ConcurrentReceiverGroup()); // Wait on this interleave until a CreateResponse is posted to nxtCommunicationResponse port. Activate(initializationInterleave); // Set up a seperate interleave which processes I2C Commands one at a time. Activate(new Interleave( new ExclusiveReceiverGroup( Arbiter.ReceiveWithIterator<SendLowSpeedCommand>(true, _internalI2CPort, I2cLowSpeedCommandHandler)), new ConcurrentReceiverGroup())); }
/// <summary> /// Service Initialization /// Connect to the Brick and then open up the service for all requests /// </summary> /// <returns></returns> public virtual IEnumerator<ITask> ServiceInitialization(CreateResponse createResponse) { // Set up the _brickPort to our communications service _brickPort = ServiceForwarder<comm.LegoCommOperations>(createResponse.Service); // Subscribe to the communications port. yield return Arbiter.Choice(_brickPort.Subscribe(_brickNotificationPort), EmptyHandler<SubscribeResponseType>, EmptyHandler<Fault>); // If the SerialPort is not set, start the service, // but do not attempt to connect to the actual hardware. bool done = (_state.Configuration.SerialPort == 0); if (!done) { // If we are not done yet, attempt to connect to the hardware. NxtBrickOperations _initPort = new NxtBrickOperations(); PortSet<DefaultUpdateResponseType, Fault> _initResponse = new PortSet<DefaultUpdateResponseType, Fault>(); ConnectToHardware connectToHardware = new ConnectToHardware(_state.Configuration, _initResponse); _initPort.Post(connectToHardware); // Special one time handler to connect to the hardware before we open up the service to receive messages. Activate<ITask>( Arbiter.ReceiveWithIterator<ConnectToHardware>(false, _initPort, ConnectToHardwareHandler), new Interleave( new TeardownReceiverGroup( Arbiter.ReceiveWithIterator<DefaultUpdateResponseType>(false, _initResponse, InitializationComplete), Arbiter.ReceiveWithIterator<Fault>(false, _initResponse, InitializationComplete), Arbiter.ReceiveWithIterator<DsspDefaultDrop>(false, _internalMainPort, DropHandler) ), new ExclusiveReceiverGroup( Arbiter.ReceiveWithIterator<AttachAndSubscribe>(true, _internalMainPort, AttachAndSubscribeHandler), Arbiter.ReceiveWithIterator<ReserveDevicePort>(true, _internalMainPort, ReserveDevicePortHandler), Arbiter.ReceiveWithIterator<Subscribe>(true, _internalMainPort, SubscribeHandler), Arbiter.ReceiveWithIterator<Detach>(true, _internalMainPort, DetachHandler), Arbiter.ReceiveWithIterator<AdjustPollingFrequency>(true, _internalMainPort, AdjustPollingFrequencyHandler) ), new ConcurrentReceiverGroup()) ); } else { SpawnIterator<DefaultUpdateResponseType>(DefaultUpdateResponseType.Instance, InitializationComplete); } yield break; }