/// <summary> /// Handle the given message /// </summary> /// <returns>True if handled</returns> protected virtual bool GetSlotData(SlotDataRequest msg) { log.Trace("Received: GetSlotData: slot={0}", msg.Slot); var slot = slotTable.FindBySlotNumber(msg.Slot, false, -1); SendSlotDataResponse(slot, msg.Slot); return(true); }
/// <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); } } }
/// <summary> /// Slot data request /// </summary> public override bool Visit(SlotDataRequest msg, Master data) { return(data.GetSlotData(msg)); }
public virtual TReturn Visit(SlotDataRequest msg, TData data) { return(default(TReturn)); }