Пример #1
0
        /// <summary>
        /// Initiate the standard address selection procedure to get/create a slot for the given loc.
        /// </summary>
        protected Slot RequestSlot(ILocState loc)
        {
            var address = loc.Address.ValueAsInt;

            log.Trace("RequestSlot(addr={0})", address);

            lock (transactionLock)
            {
                var slot = locSlotMap[loc];
                if ((slot != null) && (slot.IsUpdate2Date))
                {
                    // Slot already available
                    return(slot);
                }

                if (slot != null)
                {
                    // Slot may be out of date
                    log.Trace("Updating slot {0} for {1}", slot.SlotNumber, address);
                    try
                    {
                        var msg      = new SlotDataRequest(slot.SlotNumber);
                        var response = msg.ExecuteAndWaitForResponse <SlotDataResponse>(
                            LocoBuffer,
                            x => (x.Address == address), RequestSlotTimeout);
                        if (response != null)
                        {
                            log.Trace("Updated slot {0} for {1}", slot.SlotNumber, address);
                            slot.Touch();
                            return(slot);
                        }
                        log.Trace("Updating slot {0} for {1} failed. Slot is different.", slot.SlotNumber, address);
                        locSlotMap.Remove(slot);
                    }
                    catch (TimeoutException ex)
                    {
                        // Ignore for now, just claim a new slot
                        locSlotMap.Remove(slot);
                    }
                }

                log.Trace("Requesting slot for {0}", address);
                var req = new LocoAddressRequest(address);
                try
                {
                    // Perform the loco-address request
                    var response = req.ExecuteAndWaitForResponse <SlotDataResponse>(
                        LocoBuffer,
                        x => (x.Address == address), RequestSlotTimeout);
                    if (response == null)
                    {
                        log.Trace("Requesting slot for {0} failed: Timeout", address);
                        throw new TimeoutException();
                    }

                    // We now got a valid slot data response
                    slot = new Slot(response);
                    log.Trace("Requesting slot for {0} succeeded: got slot {1}", address, slot.SlotNumber);

                    // Get status
                    var usageStatus = response.Status1 & SlotStatus1.BusyActiveMask;
                    if ((usageStatus == SlotStatus1.InUse) || (response.Status1.IsSet(SlotStatus1.ConsistUp)))
                    {
                        // We're not allowed to use this slot
                        log.Trace("Slot status does not allow to use the slot: {0}", response.Status1);
                        return(null);
                    }

                    // We can use the slot, perform a NULL move to set it in use.
                    log.Trace("Request NULL move for slot {0}, address {1}", slot.SlotNumber, address);
                    var msg          = new MoveSlotsRequest(slot.SlotNumber, slot.SlotNumber);
                    var moveResponse = msg.ExecuteAndWaitForResponse <SlotDataResponse>(
                        LocoBuffer,
                        x => (x.Address == address), RequestSlotTimeout);
                    if (moveResponse == null)
                    {
                        log.Trace("NULL move for slot {0}, address {1} failed: timeout", slot.SlotNumber, address);
                        return(null);
                    }

                    // We can now use the slot
                    log.Trace("Request NULL move for slot {0}, address {1} succeeded", slot.SlotNumber, address);
                    locSlotMap[loc] = slot;

                    // Set decoder type
                    var status = UpdateDecoderType(response.Status1, loc);
                    log.Trace("Write slot {0} stat1 {1} for address {2}", slot.SlotNumber, status, address);
                    var slotStat1Msg = new SlotStat1Request(response.Slot, status);
                    slotStat1Msg.Execute(lb);

                    return(slot);
                }
                catch (TimeoutException)
                {
                    // No proper response
                    log.Trace("Timeout on slot request for {0}", address);
                    return(null);
                }
            }
        }
Пример #2
0
 public virtual TReturn Visit(SlotStat1Request msg, TData data)
 {
     return(default(TReturn));
 }