private bool CheckWakeUp() { long now = GetUtcTimeInterruptsDisabled(); bool foundSleeper = false; // TODO: more efficient data structure foreach (Thread t in threadTable) { if (t != null) { WakeUp wakeUp = t.wakeUp; if (wakeUp != null) { foundSleeper = true; if (now - wakeUp.time >= 0) { // time to wake up wakeUp.queue.Remove(t); t.wakeUp = null; readyQueue.Enqueue(t); } } } } return(foundSleeper); }
/// <summary> /// Implements the ResourceLock's DoneWriting behavior. /// </summary> protected override void OnLeave(Boolean write) { Debug.Assert(State(m_LockState) == OneLockStates.OwnedByWriter); // Pre-condition: Lock's state must be OBW (not Free) // Post-condition: Lock's state must become Free (the lock is never passed) // Phase 1: Release the lock WakeUp wakeup = DoneWriting(ref m_LockState); // Phase 2: Possibly wake waiters switch (wakeup) { case WakeUp.None: break; case WakeUp.Writer: Int32 numWritersToWake = NumWritersToWake(); Debug.Assert(numWritersToWake < 2); // Must be 0 or 1 if (numWritersToWake > 0) { m_WritersLock.Release(numWritersToWake); } break; } }
private static WakeUp DoneReading(ref Int32 target) { Int32 i, j = target; WakeUp wakeup = WakeUp.None; do { i = j; Int32 desired = i; DecReadersReading(ref desired); // RR-- // if RR>0 -> readers still reading, return if (NumReadersReading(desired) > 0) { } else // No more readers reading // if WW>0 -> RFW, return { if (NumWritersWaiting(desired) > 0) { State(ref desired, OneManyLockStates.ReservedForWriter); wakeup = WakeUp.Writer; } else { // All readers left and No waiting writers State(ref desired, OneManyLockStates.Free); } } j = Interlocked.CompareExchange(ref target, desired, i); } while (i != j); return(wakeup); }
private bool Wait(WakeUp wakeUp) { try { CompilerIntrinsics.Cli(); if (waitSemaphore == null) { waitSemaphore = Kernel.kernel.NewSemaphore(0); } uint depth = lockDepth; uint cur = Kernel.CurrentThread; lockHolder = 0xffffffff; lockDepth = 0; lockSemaphore.SignalInterruptsDisabled(); bool gotIt = waitSemaphore.WaitInterruptsDisabled(wakeUp); lockSemaphore.WaitInterruptsDisabled(); lockDepth = depth; lockHolder = cur; return(gotIt); } finally { CompilerIntrinsics.Sti(); } }
private void wakeUpSelectedMachine_Click(object sender, EventArgs e) { var objWakeU = new WakeUp(); var objMachine = ListOfMachines.Where(x => x.MachineName == SelectedMachineName).FirstOrDefault(); objWakeU.WakeFunction(objMachine.MachineMACAddress.Replace(":", "-").Replace("-", "")); }
public void InitWakUpSleep() { WakeUp.SetWakeAtByConfig( () => { InitWakUpSleep(); }); Sleeper.WaitForSleepByConfig(); }
private static WakeUp DoneWriting(ref Int32 target) { Int32 i, j = target; WakeUp wakeup = WakeUp.None; do { i = j; Int32 desired = i; // if WW=0 && RW=0 -> Free if ((NumWritersWaiting(desired) == 0) && (NumReadersWaiting(desired) == 0)) { State(ref desired, OneManyLockStates.Free); } else { // if WW>0 && RW=0 -> RFW, possibly release a writer if ((NumWritersWaiting(desired) > 0) && (NumReadersWaiting(desired) == 0)) { State(ref desired, OneManyLockStates.ReservedForWriter); wakeup = WakeUp.Writer; } else { // if WW>0 && RW>0 -> RFW, possibly release a writer if ((NumWritersWaiting(desired) > 0) && (NumReadersWaiting(desired) > 0)) { // JMR: Merge with above - is this even possible? State(ref desired, OneManyLockStates.ReservedForWriter); wakeup = WakeUp.Writer; } else { // if WW=0 && RW>0 -> Free, possibly release readers if ((NumWritersWaiting(desired) == 0) && (NumReadersWaiting(desired) > 0)) { State(ref desired, OneManyLockStates.Free); wakeup = WakeUp.Readers; } else { Debug.Assert(false, "Invalid Lock state"); } } } } j = Interlocked.CompareExchange(ref target, desired, i); } while (i != j); return(wakeup); }
private static WakeUp DoneWriting(ref Int32 target) { Int32 i, j = target; WakeUp wakeup = WakeUp.None; do { i = j; Int32 desired = i; // The lock should become free State(ref desired, OneLockStates.Free); // Possible wake a waiting writer wakeup = (NumWritersWaiting(desired) > 0) ? WakeUp.Writer : WakeUp.None; j = Interlocked.CompareExchange(ref target, desired, i); } while (i != j); return(wakeup); }
private bool WaitOne(WakeUp wakeUp) { try { CompilerIntrinsics.Cli(); if (isSet) { return(true); } else { return(waitSemaphore.WaitInterruptsDisabled(wakeUp)); } } finally { CompilerIntrinsics.Sti(); } }
internal bool Acquire(WakeUp wakeUp) { try { CompilerIntrinsics.Cli(); uint cur = Kernel.CurrentThread; if (lockHolder == cur) { lockDepth++; return(true); } bool gotIt = lockSemaphore.WaitInterruptsDisabled(wakeUp); lockHolder = cur; return(gotIt); // TODO: return value doesn't match documentation, but should it? } finally { CompilerIntrinsics.Sti(); } }
protected virtual void OnWakeUp(WakeUpEventArgs e) { WakeUp?.Invoke(this, e); }
public void SetAlarm(string input) { Parse(input); WakeUp.Invoke(this, $"Time: {_hours} : {_minutes}"); }
private void ZwaveMessageReceived(object sender, ZWaveMessageReceivedEventArgs args) { // discard repeated messages within last 2 seconds time range bool repeated = false; if (lastMessage != null) { var elapsed = (DateTime.UtcNow - lastMessageTimestamp); if (elapsed.TotalSeconds <= 2 && lastMessage.SequenceEqual(args.Message)) { //Utility.DebugLog(DebugMessageType.Information, " lastMessage: " + Utility.ByteArrayToString(lastMessage)); //Utility.DebugLog(DebugMessageType.Information, "args.Message: " + Utility.ByteArrayToString(args.Message)); repeated = true; } } lastMessageTimestamp = DateTime.UtcNow; lastMessage = new byte[args.Message.Length]; //Utility.DebugLog(DebugMessageType.Information, " lastMessage2: " + Utility.ByteArrayToString(lastMessage)); //Utility.DebugLog(DebugMessageType.Information, "args.Message2: " + Utility.ByteArrayToString(args.Message)); Buffer.BlockCopy(args.Message, 0, lastMessage, 0, args.Message.Length * sizeof(byte)); if (repeated) { Utility.DebugLog(DebugMessageType.Warning, "Repeated message discarded."); return; } // int length = args.Message.Length; try { MessageHeader zwaveHeader = (MessageHeader)args.Message[0]; switch (zwaveHeader) { case MessageHeader.CAN: // RESEND ?!?! break; case MessageHeader.ACK: break; case MessageHeader.SOF: // start of zwave frame var messageType = MessageType.None; Enum.TryParse(args.Message[2].ToString(), out messageType); var functionType = Function.None; Enum.TryParse(args.Message[3].ToString(), out functionType); switch (messageType) { case MessageType.Request: if (devices.Count == 0) { break; } switch (functionType) { case Function.None: break; case Function.NodeAdd: var nodeAddStatus = NodeFunctionStatus.None; Enum.TryParse(args.Message[5].ToString(), out nodeAddStatus); switch (nodeAddStatus) { case NodeFunctionStatus.AddNodeAddingSlave: nodeOperationIdCheck = args.Message[6]; var newNode = CreateDevice(nodeOperationIdCheck, 0x00); // Extract node information frame int nodeInfoLength = (int)args.Message[7]; // we don't need to exclude the last 2 CommandClasses byte[] nodeInfo = new byte[nodeInfoLength]; Array.Copy(args.Message, 8, nodeInfo, 0, nodeInfoLength); newNode.NodeInformationFrame = nodeInfo; newNode.BasicClass = args.Message[8]; newNode.GenericClass = args.Message[9]; newNode.SpecificClass = args.Message[10]; devices.Add(newNode); if (newNode.SupportCommandClass(CommandClass.Security)) { var nodeSecurityData = Security.GetSecurityData(newNode); nodeSecurityData.IsAddingNode = true; Security.GetScheme(newNode); } else { NodeInformationFrameComplete(newNode); } break; //case NodeFunctionStatus.AddNodeDone: case NodeFunctionStatus.AddNodeProtocolDone: if (nodeOperationIdCheck == args.Message[6]) { Thread.Sleep(500); GetNodeCapabilities(args.Message[6]); var addedNode = devices.Find(n => n.Id == args.Message[6]); if (addedNode != null) { ManufacturerSpecific.Get(addedNode); } } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.NodeAdded)); // force refresh of nodelist sending DiscoverEnd event // TODO: deprecate this and update the Web UI to refresh modules list on NodeAdded event OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); break; case NodeFunctionStatus.AddNodeFailed: Utility.DebugLog(DebugMessageType.Warning, "ADDING NODE FAILED (" + args.Message[6] + ")"); break; } break; case Function.NodeRemove: var nodeRemoveStatus = NodeFunctionStatus.None; Enum.TryParse(args.Message[5].ToString(), out nodeRemoveStatus); switch (nodeRemoveStatus) { case NodeFunctionStatus.RemoveNodeRemovingSlave: nodeOperationIdCheck = args.Message[6]; break; case NodeFunctionStatus.RemoveNodeDone: if (nodeOperationIdCheck == args.Message[6]) { RemoveDevice(nodeOperationIdCheck); } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.NodeRemoved)); // force refresh of nodelist sending DiscoverEnd event // TODO: deprecate this and update the Web UI to refresh modules list on NodeRemoved event OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); break; case NodeFunctionStatus.RemoveNodeFailed: OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.NodeError)); Utility.DebugLog(DebugMessageType.Warning, "REMOVING NODE FAILED (" + args.Message[6] + ")"); break; } break; case Function.ApplicationCommandHandler: var node = devices.Find(n => n.Id == args.Message[5]); if (node != null) { try { node.ApplicationCommandHandler(args.Message); } catch (Exception ex) { Utility.DebugLog(DebugMessageType.Error, "Exception occurred in node.ApplicationCommandHandler: " + ex.Message + "\n" + ex.StackTrace); } } else { Utility.DebugLog(DebugMessageType.Error, "Unknown node id " + args.Message[5]); } break; case Function.SendData: byte callbackId = args.Message[4]; if (callbackId == 0x01) // 0x01 is "SEND DATA OK" { // TODO: ... is there anything to be done here? } else { var status = CallbackStatus.Nack; Enum.TryParse(args.Message[5].ToString(), out status); switch (status) { case CallbackStatus.Ack: // Messaging complete, remove callbackid zwavePort.NodeRequestAck(callbackId); break; case CallbackStatus.Nack: var pendingMessage = zwavePort.NodeRequestNack(callbackId); if (pendingMessage != null && pendingMessage.ResendCount >= ZWaveMessage.ResendMaxAttempts) { // Resend timed out OnControllerEvent(new ControllerEventArgs(pendingMessage.Node.Id, ControllerStatus.NodeError)); // Check if node supports WakeUp class, and add message to wake up message queue if (pendingMessage != null) { var sleepingNode = pendingMessage.Node; if (sleepingNode != null && sleepingNode.SupportCommandClass(CommandClass.WakeUp)) { WakeUp.ResendOnWakeUp(sleepingNode, pendingMessage.Message); } } } break; case CallbackStatus.NeighborUpdateStarted: // Neighbour Update Options STARTED //var message = zwavePort.GetPendingMessage(commandId); // TODO: don't know what to do here... break; case CallbackStatus.NeighborUpdateDone: var message = zwavePort.GetPendingMessage(callbackId); if (message != null) { RequestNeighborsUpdate(message.Node); // send ack so the message is removed from the pending message list zwavePort.NodeRequestAck(callbackId); } break; } } break; case Function.ApplicationUpdate: int nifLength = (int)args.Message[6]; var znode = devices.Find(n => n.Id == args.Message[5]); if (znode != null) { // we don't need to exclude the last 2 CommandClasses byte[] nodeInfo = new byte[nifLength]; Array.Copy(args.Message, 7, nodeInfo, 0, nifLength); znode.NodeInformationFrame = nodeInfo; if (znode.SupportCommandClass(CommandClass.Security)) { // ask the node what security command classes are supported Security.GetSupported(znode); } else { NodeInformationFrameComplete(znode); } } break; case Function.RequestNodeNeighborsUpdateOptions: case Function.RequestNodeNeighborsUpdate: var neighborUpdateStatus = NeighborsUpdateStatus.None; Enum.TryParse(args.Message[5].ToString(), out neighborUpdateStatus); var pm = zwavePort.GetPendingMessage(args.Message[4]); switch (neighborUpdateStatus) { case NeighborsUpdateStatus.NeighborsUpdateStared: OnControllerEvent(new ControllerEventArgs(pm.Node.Id, ControllerStatus.NeighborUpdateStarted)); break; case NeighborsUpdateStatus.NeighborsUpdateDone: nodeOperationIdCheck = pm.Node.Id; OnControllerEvent(new ControllerEventArgs(nodeOperationIdCheck, ControllerStatus.NeighborUpdateDone)); GetNeighborsRoutingInfo(pm.Node); if (pm != null) { zwavePort.NodeRequestAck(pm.CallbackId); } break; case NeighborsUpdateStatus.NeighborsUpdateFailed: OnControllerEvent(new ControllerEventArgs(pm.Node.Id, ControllerStatus.NeighborUpdateFailed)); if (pm != null) { zwavePort.NodeRequestNack(pm.CallbackId); } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled Node Neighbor Update REQUEST " + Utility.ByteArrayToString(args.Message)); break; } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled REQUEST " + Utility.ByteArrayToString(args.Message)); break; } break; case MessageType.Response: switch (functionType) { case Function.DiscoveryNodes: NodeBitMaskResponseHandler(args.Message); break; case Function.GetNodeProtocolInfo: NodeCapabilitiesResponseHandler(args.Message); break; case Function.RequestNodeInfo: // TODO: shall we do something here? break; case Function.SendData: // TODO: shall we do something here? break; case Function.GetRoutingInfo: var routingInfo = ExtractRoutingFromBitMask(args.Message); if (routingInfo.Count > 0) { var routedNode = devices.Find(n => n.Id == nodeOperationIdCheck); if (routedNode != null) { // routedNode.RaiseUpdateParameterEvent(new ZWaveEvent(routedNode, EventParameter.RoutingInfo, String.Join(" ", routingInfo), 0)); } } else { Utility.DebugLog(DebugMessageType.Warning, "No routing nodes reported."); } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled RESPONSE " + Utility.ByteArrayToString(args.Message)); break; } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled MESSAGE TYPE " + Utility.ByteArrayToString(args.Message)); break; } break; } } catch (Exception ex) { Utility.DebugLog(DebugMessageType.Error, "Exception occurred :" + ex.Message + "\n" + ex.StackTrace); } }
public object InterfaceControl(MigInterfaceCommand request) { ResponseText returnValue = new ResponseText("OK"); bool raiseEvent = false; string eventParameter = ModuleEvents.Status_Level; string eventValue = ""; string nodeId = request.Address; Commands command; Enum.TryParse <Commands>(request.Command.Replace(".", "_"), out command); ZWaveNode node = null; byte nodeNumber = 0; if (byte.TryParse(nodeId, out nodeNumber)) { if (nodeNumber > 0) { node = controller.GetNode(nodeNumber); } switch (command) { case Commands.Controller_Discovery: controller.Discovery(); break; case Commands.Controller_SoftReset: controller.SoftReset(); break; case Commands.Controller_HardReset: controller.HardReset(); controller.Discovery(); break; case Commands.Controller_HealNetwork: controller.HealNetwork(); break; case Commands.Controller_NodeNeighborUpdate: controller.RequestNeighborsUpdateOptions(nodeNumber); controller.RequestNeighborsUpdate(nodeNumber); controller.GetNeighborsRoutingInfo(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_RoutingInfo); break; case Commands.Controller_NodeRoutingInfo: controller.GetNeighborsRoutingInfo(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_RoutingInfo); break; case Commands.Controller_NodeAdd: lastAddedNode = 0; controller.BeginNodeAdd(); for (int i = 0; i < 20; i++) { if (lastAddedNode > 0) { break; } Thread.Sleep(500); } controller.StopNodeAdd(); returnValue = new ResponseText(lastAddedNode.ToString()); break; case Commands.Controller_NodeRemove: lastRemovedNode = 0; controller.BeginNodeRemove(); for (int i = 0; i < 20; i++) { if (lastRemovedNode > 0) { break; } Thread.Sleep(500); } controller.StopNodeRemove(); returnValue = new ResponseText(lastRemovedNode.ToString()); break; case Commands.Basic_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); Basic.Set(node, (byte)level); } break; case Commands.Basic_Get: Basic.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_Basic); break; case Commands.SwitchBinary_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); SwitchBinary.Set(node, (byte)level); } break; case Commands.SwitchBinary_Get: SwitchBinary.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_SwitchBinary); break; case Commands.SwitchMultilevel_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); SwitchMultilevel.Set(node, (byte)level); } break; case Commands.SwitchMultilevel_Get: SwitchMultilevel.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_SwitchMultilevel); break; case Commands.MultiInstance_GetCount: { string commandType = request.GetOption(0).Replace(".", ""); switch (commandType) { case "SwitchBinary": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SwitchBinary); break; case "SwitchMultiLevel": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SwitchMultilevel); break; case "SensorBinary": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SensorBinary); break; case "SensorMultiLevel": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SensorMultilevel); break; } returnValue = GetResponseValue(nodeNumber, EventPath_MultiInstance + "." + commandType + ".Count"); } break; case Commands.MultiInstance_Get: { byte instance = (byte)int.Parse(request.GetOption(1)); string commandType = request.GetOption(0).Replace(".", ""); switch (commandType) { case "SwitchBinary": MultiInstance.SwitchBinaryGet(node, instance); break; case "SwitchMultiLevel": MultiInstance.SwitchMultiLevelGet(node, instance); break; case "SensorBinary": MultiInstance.SensorBinaryGet(node, instance); break; case "SensorMultiLevel": MultiInstance.SensorMultiLevelGet(node, instance); break; } returnValue = GetResponseValue(nodeNumber, EventPath_MultiInstance + "." + commandType + "." + instance); } break; case Commands.MultiInstance_Set: { byte instance = (byte)int.Parse(request.GetOption(1)); int value = int.Parse(request.GetOption(2)); // //raisepropchanged = true; //parampath += "." + instance; // Status.Level.<instance> // switch (request.GetOption(0)) { case "Switch.Binary": MultiInstance.SwitchBinarySet(node, instance, value); //raiseparam = (double.Parse(request.GetOption(2)) / 255).ToString(); break; case "Switch.MultiLevel": MultiInstance.SwitchMultiLevelSet(node, instance, value); //raiseparam = (double.Parse(request.GetOption(2)) / 100).ToString(); // TODO: should it be 99 ? break; } } break; case Commands.SensorBinary_Get: SensorBinary.Get(node); break; case Commands.SensorMultiLevel_Get: SensorMultilevel.Get(node); break; case Commands.Meter_Get: // see ZWaveLib Sensor.cs for EnergyMeterScale options int scaleType = 0; int.TryParse(request.GetOption(0), out scaleType); Meter.Get(node, (byte)(scaleType << 0x03)); break; case Commands.Meter_SupportedGet: Meter.GetSupported(node); break; case Commands.Meter_Reset: Meter.Reset(node); break; case Commands.NodeInfo_Get: controller.GetNodeInformationFrame(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_NodeInfo); break; case Commands.Battery_Get: Battery.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_Battery); break; case Commands.Association_Set: Association.Set(node, (byte)int.Parse(request.GetOption(0)), (byte)int.Parse(request.GetOption(1))); break; case Commands.Association_Get: byte group = (byte)int.Parse(request.GetOption(0)); Association.Get(node, group); returnValue = GetResponseValue(nodeNumber, EventPath_Associations + "." + group); break; case Commands.Association_Remove: Association.Remove(node, (byte)int.Parse(request.GetOption(0)), (byte)int.Parse(request.GetOption(1))); break; case Commands.ManufacturerSpecific_Get: ManufacturerSpecific.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_ManufacturerSpecific); break; case Commands.Config_ParameterSet: Configuration.Set(node, (byte)int.Parse(request.GetOption(0)), int.Parse(request.GetOption(1))); break; case Commands.Config_ParameterGet: byte position = (byte)int.Parse(request.GetOption(0)); Configuration.Get(node, position); returnValue = GetResponseValue(nodeNumber, EventPath_ConfigVariables + "." + position); break; case Commands.WakeUp_Get: WakeUp.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_WakeUpInterval); break; case Commands.WakeUp_Set: WakeUp.Set(node, uint.Parse(request.GetOption(0))); break; case Commands.WakeUp_SendToSleep: WakeUp.SendToSleep(node); break; case Commands.WakeUp_GetAlwaysAwake: returnValue = new ResponseText(WakeUp.GetAlwaysAwake(node) ? "1" : "0"); break; case Commands.WakeUp_SetAlwaysAwake: WakeUp.SetAlwaysAwake(node, uint.Parse(request.GetOption(0)) == 1 ? true : false); break; case Commands.Version_Get: returnValue = new ResponseText("ERROR"); CommandClass cclass; Enum.TryParse <CommandClass>(request.GetOption(0), out cclass); if (cclass != CommandClass.NotSet) { var nodeCclass = node.GetCommandClass(cclass); if (nodeCclass != null && nodeCclass.Version != 0) { returnValue = new ResponseText(nodeCclass.Version.ToString()); } else { ZWaveLib.CommandClasses.Version.Get(node, cclass); returnValue = GetResponseValue(nodeNumber, "ZWaveNode.Version." + cclass); } } break; case Commands.Version_GetAll: controller.GetNodeCcsVersion(node); break; case Commands.Control_On: raiseEvent = true; double lastLevel = GetNormalizedValue((double)GetNodeLastLevel(node)); eventValue = lastLevel > 0 ? lastLevel.ToString(CultureInfo.InvariantCulture) : "1"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0xFF); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0xFF); } else { Basic.Set(node, 0xFF); } SetNodeLevel(node, 0xFF); break; case Commands.Control_Off: raiseEvent = true; eventValue = "0"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0x00); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0x00); } else { Basic.Set(node, 0x00); } SetNodeLevel(node, 0x00); break; case Commands.Control_Level: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = Math.Round(level / 100D, 2).ToString(CultureInfo.InvariantCulture); // the max value should be obtained from node parameters specifications, // here we assume that the commonly used interval is [0-99] for most multilevel switches if (level >= 100) { level = 99; } if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, (byte)level); } else { Basic.Set(node, (byte)level); } SetNodeLevel(node, (byte)level); } break; case Commands.Control_Toggle: raiseEvent = true; if (GetNodeLevel(node) == 0) { double lastOnLevel = GetNormalizedValue((double)GetNodeLastLevel(node)); eventValue = lastOnLevel > 0 ? lastOnLevel.ToString(CultureInfo.InvariantCulture) : "1"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0xFF); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0xFF); } else { Basic.Set(node, 0xFF); } SetNodeLevel(node, 0xFF); } else { eventValue = "0"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0x00); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0x00); } else { Basic.Set(node, 0x00); } SetNodeLevel(node, 0x00); } break; case Commands.Thermostat_ModeGet: ThermostatMode.Get(node); break; case Commands.Thermostat_ModeSet: { ThermostatMode.Value mode = (ThermostatMode.Value)Enum.Parse(typeof(ThermostatMode.Value), request.GetOption(0)); // raiseEvent = true; eventParameter = "Thermostat.Mode"; eventValue = request.GetOption(0); // ThermostatMode.Set(node, mode); } break; case Commands.Thermostat_SetPointGet: { ThermostatSetPoint.Value mode = (ThermostatSetPoint.Value)Enum.Parse(typeof(ThermostatSetPoint.Value), request.GetOption(0)); ThermostatSetPoint.Get(node, mode); } break; case Commands.Thermostat_SetPointSet: { ThermostatSetPoint.Value mode = (ThermostatSetPoint.Value)Enum.Parse(typeof(ThermostatSetPoint.Value), request.GetOption(0)); double temperature = double.Parse(request.GetOption(1).Replace(',', '.'), CultureInfo.InvariantCulture); // raiseEvent = true; eventParameter = "Thermostat.SetPoint." + request.GetOption(0); eventValue = temperature.ToString(CultureInfo.InvariantCulture); // ThermostatSetPoint.Set(node, mode, temperature); } break; case Commands.Thermostat_FanModeGet: ThermostatFanMode.Get(node); break; case Commands.Thermostat_FanModeSet: { ThermostatFanMode.Value mode = (ThermostatFanMode.Value)Enum.Parse(typeof(ThermostatFanMode.Value), request.GetOption(0)); // raiseEvent = true; eventParameter = "Thermostat.FanMode"; eventValue = request.GetOption(0); // ThermostatFanMode.Set(node, mode); } break; case Commands.Thermostat_FanStateGet: ThermostatFanState.Get(node); break; case Commands.Thermostat_OperatingStateGet: ThermostatOperatingState.GetOperatingState(node); break; case Commands.UserCode_Set: byte userId = byte.Parse(request.GetOption(0)); byte userIdStatus = byte.Parse(request.GetOption(1)); byte[] tagCode = ZWaveLib.Utility.HexStringToByteArray(request.GetOption(2)); UserCode.Set(node, new ZWaveLib.Values.UserCodeValue(userId, userIdStatus, tagCode)); break; case Commands.DoorLock_Get: DoorLock.Get(node); returnValue = GetResponseValue(nodeNumber, ModuleEvents.Status_DoorLock); break; case Commands.DoorLock_Set: { DoorLock.Value mode = (DoorLock.Value)Enum.Parse(typeof(DoorLock.Value), request.GetOption(0)); DoorLock.Set(node, mode); } break; } } if (raiseEvent) { //ZWaveNode node = _controller.GetDevice ((byte)int.Parse (nodeid)); OnInterfacePropertyChanged(this.GetDomain(), nodeId, "ZWave Node", eventParameter, eventValue); } // return(returnValue); }
protected void OnWakeUp() { WakeUp.Invoke(this, EventArgs.Empty); }
private void ZwaveMessageReceived(object sender, ZWaveMessageReceivedEventArgs args) { // discard repeated messages within last 2 seconds time range bool repeated = false; if (lastMessage != null) { var elapsed = (DateTime.UtcNow - lastMessageTimestamp); if (elapsed.TotalSeconds <= 2 && lastMessage.SequenceEqual(args.Message)) { //Utility.DebugLog(DebugMessageType.Information, " lastMessage: " + Utility.ByteArrayToString(lastMessage)); //Utility.DebugLog(DebugMessageType.Information, "args.Message: " + Utility.ByteArrayToString(args.Message)); repeated = true; } } lastMessageTimestamp = DateTime.UtcNow; lastMessage = new byte[args.Message.Length]; //Utility.DebugLog(DebugMessageType.Information, " lastMessage2: " + Utility.ByteArrayToString(lastMessage)); //Utility.DebugLog(DebugMessageType.Information, "args.Message2: " + Utility.ByteArrayToString(args.Message)); Buffer.BlockCopy(args.Message, 0, lastMessage, 0, args.Message.Length * sizeof(byte)); if (repeated) { Utility.DebugLog(DebugMessageType.Warning, "Repeated message discarded."); return; } // int length = args.Message.Length; try { MessageHeader zwaveHeader = (MessageHeader)args.Message[0]; switch (zwaveHeader) { case MessageHeader.CAN: // RESEND //Utility.DebugLog(DebugMessageType.Warning, "Received CAN, resending last message"); //zp.ResendLastMessage(); break; case MessageHeader.ACK: break; case MessageHeader.SOF: // start of zwave frame // // parse frame headers // //int msgLength = (int)args.Message[1]; var msgType = (MessageType)args.Message[2]; var function = (args.Message.Length > 3 ? (Function)args.Message[3] : 0); byte sourceNodeId = 0; byte nodeOperation = 0; // switch (msgType) { case MessageType.Request: if (devices.Count == 0) { break; } switch (function) { case Function.None: break; case Function.NodeAdd: nodeOperation = args.Message[5]; if (nodeOperation == (byte)NodeFunctionStatus.AddNodeAddingSlave) { nodeOperationIdCheck = args.Message[6]; var newNode = CreateDevice(nodeOperationIdCheck, 0x00); // Extract node information frame int nodeInfoLength = (int)args.Message[7]; // we don't need to exclude the last 2 CommandClasses byte[] nodeInfo = new byte[nodeInfoLength]; Array.Copy(args.Message, 8, nodeInfo, 0, nodeInfoLength); newNode.NodeInformationFrame = nodeInfo; newNode.BasicClass = args.Message[8]; newNode.GenericClass = args.Message[9]; newNode.SpecificClass = args.Message[10]; devices.Add(newNode); if (newNode.SupportCommandClass(CommandClass.Security)) { var nodeSecurityData = Security.GetSecurityData(newNode); nodeSecurityData.IsAddingNode = true; Security.GetScheme(newNode); } else { gotNodeUpdateInformation(newNode); } } else if (nodeOperation == (byte)NodeFunctionStatus.AddNodeProtocolDone /* || nodeOperation == (byte)NodeFunctionStatus.AddNodeDone */) { if (nodeOperationIdCheck == args.Message[6]) { Thread.Sleep(500); GetNodeCapabilities(args.Message[6]); var newNode = devices.Find(n => n.Id == args.Message[6]); if (newNode != null) { ManufacturerSpecific.Get(newNode); } } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); } else if (nodeOperation == (byte)NodeFunctionStatus.AddNodeFailed) { Utility.DebugLog(DebugMessageType.Warning, "ADDING NODE FAILED (" + args.Message[6] + ")"); } break; case Function.NodeRemove: nodeOperation = args.Message[5]; if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeRemovingSlave) { nodeOperationIdCheck = args.Message[6]; } else if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeDone) { if (nodeOperationIdCheck == args.Message[6]) { RemoveDevice(args.Message[6]); } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); } else if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeFailed) { Utility.DebugLog(DebugMessageType.Warning, "REMOVING NODE FAILED (" + args.Message[6] + ")"); } break; case Function.ApplicationCommand: sourceNodeId = args.Message[5]; var node = devices.Find(n => n.Id == sourceNodeId); if (node != null) { try { node.MessageRequestHandler(args.Message); } catch (Exception ex) { Utility.DebugLog(DebugMessageType.Error, "Exception occurred in node.MessageRequestHandler: " + ex.Message + "\n" + ex.StackTrace); } } else { Utility.DebugLog(DebugMessageType.Error, "Unknown node id " + sourceNodeId); } break; case Function.SendData: byte commandId = args.Message[4]; if (commandId == 0x01) // SEND DATA OK { // TODO: ... what does that mean? } else if (args.Message[5] == 0x00) { // Messaging complete, remove callbackid zwavePort.PendingMessages.RemoveAll(zm => zm.CallbackId == commandId); } else if (args.Message[5] == 0x01) { var unsentMessage = zwavePort.PendingMessages.Find(zm => zm.CallbackId == commandId); byte nodeID = zwavePort.ResendLastMessage(commandId); if (nodeID != 0) { // Resend timed out OnControllerEvent(new ControllerEventArgs(nodeID, ControllerStatus.NodeError)); // Check if node supports WakeUp class, and add message to wake up message queue if (unsentMessage != null) { var sleepingNode = devices.Find(n => n.Id == nodeID); if (sleepingNode != null && sleepingNode.SupportCommandClass(CommandClass.WakeUp)) { WakeUp.ResendOnWakeUp(sleepingNode, unsentMessage.Message); } } } } break; case Function.NodeUpdateInfo: sourceNodeId = args.Message[5]; int nifLength = (int)args.Message[6]; var znode = devices.Find(n => n.Id == sourceNodeId); if (znode != null) { // we don't need to exclude the last 2 CommandClasses byte[] nodeInfo = new byte[nifLength]; Array.Copy(args.Message, 7, nodeInfo, 0, nifLength); znode.NodeInformationFrame = nodeInfo; if (znode.SupportCommandClass(CommandClass.Security)) { // ask the node what security command classes are supported Security.GetSupported(znode); } else { gotNodeUpdateInformation(znode); } } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled REQUEST " + Utility.ByteArrayToString(args.Message)); break; } break; case MessageType.Response: switch (function) { case Function.DiscoveryNodes: MessageResponseNodeBitMaskHandler(args.Message); break; case Function.GetNodeProtocolInfo: MessageResponseNodeCapabilityHandler(args.Message); break; case Function.RequestNodeInfo: // TODO: shall we do something here? break; case Function.SendData: // TODO: shall we do something here? break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled RESPONSE " + Utility.ByteArrayToString(args.Message)); break; } break; default: Utility.DebugLog(DebugMessageType.Warning, "Unhandled MESSAGE TYPE " + Utility.ByteArrayToString(args.Message)); break; } break; } } catch (Exception ex) { Utility.DebugLog(DebugMessageType.Error, "Exception occurred :" + ex.Message + "\n" + ex.StackTrace); } }
public virtual bool MessageRequestHandler(byte[] receivedMessage) { //Console.WriteLine("\n _z_ [" + this.NodeId + "] " + (this.DeviceHandler != null ? this.DeviceHandler.ToString() : "!" + this.GenericClass.ToString())); //Console.WriteLine(" >>> " + zp.ByteArrayToString(receivedMessage) + "\n"); ZWaveEvent messageEvent = null; int messageLength = receivedMessage.Length; if (messageLength > 8) { //byte commandLength = receivedMessage[6]; byte commandClass = receivedMessage[7]; switch (commandClass) { case (byte)CommandClass.Basic: messageEvent = Basic.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Alarm: messageEvent = Alarm.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SensorAlarm: messageEvent = SensorAlarm.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SceneActivation: messageEvent = SceneActivation.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SwitchBinary: messageEvent = SwitchBinary.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SwitchMultilevel: messageEvent = SwitchMultilevel.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SensorBinary: messageEvent = SensorBinary.GetEvent(this, receivedMessage); break; case (byte)CommandClass.SensorMultilevel: messageEvent = SensorMultilevel.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Meter: messageEvent = Meter.GetEvent(this, receivedMessage); break; case (byte)CommandClass.ThermostatMode: case (byte)CommandClass.ThermostatFanMode: case (byte)CommandClass.ThermostatFanState: case (byte)CommandClass.ThermostatHeating: case (byte)CommandClass.ThermostatOperatingState: case (byte)CommandClass.ThermostatSetBack: case (byte)CommandClass.ThermostatSetPoint: messageEvent = Thermostat.GetEvent(this, receivedMessage); break; case (byte)CommandClass.UserCode: messageEvent = UserCode.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Association: messageEvent = Association.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Configuration: messageEvent = Configuration.GetEvent(this, receivedMessage); break; case (byte)CommandClass.WakeUp: messageEvent = WakeUp.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Battery: messageEvent = Battery.GetEvent(this, receivedMessage); break; case (byte)CommandClass.Hail: Basic.Get(this); break; case (byte)CommandClass.MultiInstance: messageEvent = MultiInstance.GetEvent(this, receivedMessage); break; case (byte)CommandClass.ManufacturerSpecific: messageEvent = ManufacturerSpecific.GetEvent(this, receivedMessage); if (messageEvent != null) { var specs = (ManufacturerSpecificInfo)messageEvent.Value; this.ManufacturerId = specs.ManufacturerId; this.TypeId = specs.TypeId; this.ProductId = specs.ProductId; if (ManufacturerSpecificResponse != null) { try { ManufacturerSpecificResponse(this, new ManufacturerSpecificResponseEventArg() { NodeId = this.NodeId, ManufacturerSpecific = specs }); } catch (Exception ex) { Console.WriteLine("ZWaveLib: Error during ManufacturerSpecificResponse callback, " + ex.Message + "\n" + ex.StackTrace); } } } break; } } if (messageEvent != null) { this.RaiseUpdateParameterEvent(messageEvent.Instance, messageEvent.Event, messageEvent.Value); } else if (messageLength > 3) { if (receivedMessage[3] != 0x13) { bool log = true; if (messageLength > 7 && /* cmd_class */ receivedMessage[7] == (byte)CommandClass.ManufacturerSpecific) { log = false; } if (log) { Console.WriteLine("ZWaveLib UNHANDLED message: " + Utility.ByteArrayToString(receivedMessage)); } } } return(false); }
private void ZwaveMessageReceived(object sender, ZWaveMessageReceivedEventArgs args) { // discard repeated messages within last 2 seconds time range bool repeated = false; if (lastMessage != null) { var elapsed = (DateTime.UtcNow - lastMessageTimestamp); if (elapsed.TotalSeconds <= 2 && lastMessage.SequenceEqual(args.Message)) { repeated = true; } } lastMessageTimestamp = DateTime.UtcNow; lastMessage = new byte[args.Message.Length]; Buffer.BlockCopy(args.Message, 0, lastMessage, 0, args.Message.Length * sizeof(byte)); if (repeated) { zwavePort.SendAck(); Console.WriteLine("ZWaveLib: repeated message discarded."); return; } // int length = args.Message.Length; try { MessageHeader zwaveHeader = (MessageHeader)args.Message[0]; switch (zwaveHeader) { case MessageHeader.CAN: zwavePort.SendAck(); // RESEND //Console.WriteLine("ZWaveLib: received CAN, resending last message"); //zp.ResendLastMessage(); break; case MessageHeader.ACK: zwavePort.SendAck(); break; case MessageHeader.SOF: // start of zwave frame // // parse frame headers // //int msgLength = (int)args.Message[1]; var msgType = (MessageType)args.Message[2]; var function = (args.Message.Length > 3 ? (Function)args.Message[3] : 0); byte sourceNodeId = 0; byte nodeOperation = 0; // switch (msgType) { case MessageType.Request: zwavePort.SendAck(); if (devices.Count == 0) { break; } switch (function) { case Function.None: break; case Function.NodeAdd: nodeOperation = args.Message[5]; if (nodeOperation == (byte)NodeFunctionStatus.AddNodeAddingSlave) { //Console.WriteLine("\n\nADDING NODE SLAVE {0}\n -> ", zp.ByteArrayToString(args.Message)); nodeOperationIdCheck = args.Message[6]; var newNode = CreateDevice(nodeOperationIdCheck, 0x00); // Extract node information frame int nodeInfoLength = (int)args.Message[7]; byte[] nodeInfo = new byte[nodeInfoLength - 2]; Array.Copy(args.Message, 8, nodeInfo, 0, nodeInfoLength - 2); newNode.NodeInformationFrame = nodeInfo; RaiseUpdateParameterEvent(new ZWaveEvent(newNode, EventParameter.NodeInfo, Utility.ByteArrayToString(nodeInfo), 0)); SaveNodesConfig(); } else if (nodeOperation == (byte)NodeFunctionStatus.AddNodeProtocolDone /* || nodeOperation == (byte)NodeFunctionStatus.AddNodeDone */) { if (nodeOperationIdCheck == args.Message[6]) { //Console.WriteLine("\n\nADDING NODE DONE {0} {1}\n\n", args.Message[6], callbackid); Thread.Sleep(500); GetNodeCapabilities(args.Message[6]); var newNode = devices.Find(n => n.Id == args.Message[6]); if (newNode != null) { ManufacturerSpecific.Get(newNode); } } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); } else if (nodeOperation == (byte)NodeFunctionStatus.AddNodeFailed) { //Console.WriteLine("\n\nADDING NODE FAIL {0}\n\n", args.Message[6]); } break; case Function.NodeRemove: nodeOperation = args.Message[5]; if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeRemovingSlave) { //Console.WriteLine("\n\nREMOVING NODE SLAVE {0}\n\n", args.Message[6]); nodeOperationIdCheck = args.Message[6]; } else if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeDone) { if (nodeOperationIdCheck == args.Message[6]) { //Console.WriteLine("\n\nREMOVING NODE DONE {0} {1}\n\n", args.Message[6], callbackid); RemoveDevice(args.Message[6]); } OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); } else if (nodeOperation == (byte)NodeFunctionStatus.RemoveNodeFailed) { //Console.WriteLine("\n\nREMOVING NODE FAIL {0}\n\n", args.Message[6]); } break; case Function.ApplicationCommand: sourceNodeId = args.Message[5]; var node = devices.Find(n => n.Id == sourceNodeId); if (node == null) { CreateDevice(sourceNodeId, 0x00); GetNodeCapabilities(sourceNodeId); } try { node.MessageRequestHandler(args.Message); } catch (Exception ex) { Console.WriteLine("# " + ex.Message + "\n" + ex.StackTrace); } break; case Function.SendData: byte commandId = args.Message[4]; if (commandId == 0x01) // SEND DATA OK { // TODO: ... what does that mean? } else if (args.Message[5] == 0x00) { // Messaging complete, remove callbackid zwavePort.PendingMessages.RemoveAll(zm => zm.CallbackId == commandId); } else if (args.Message[5] == 0x01) { var unsentMessage = zwavePort.PendingMessages.Find(zm => zm.CallbackId == commandId); byte nodeID = zwavePort.ResendLastMessage(commandId); if (nodeID != 0) { // Resend timed out OnControllerEvent(new ControllerEventArgs(nodeID, ControllerStatus.NodeError)); // Check if node supports WakeUp class, and add message to wake up message queue if (unsentMessage != null) { var sleepingNode = devices.Find(n => n.Id == nodeID); if (sleepingNode != null && sleepingNode.SupportCommandClass(CommandClass.WakeUp)) { WakeUp.ResendOnWakeUp(sleepingNode, unsentMessage.Message); } } } } break; case Function.NodeUpdateInfo: sourceNodeId = args.Message[5]; int nifLength = (int)args.Message[6]; var znode = devices.Find(n => n.Id == sourceNodeId); if (znode != null) { byte[] nodeInfo = new byte[nifLength - 2]; //Console.WriteLine(ByteArrayToString(args.Message)); Array.Copy(args.Message, 7, nodeInfo, 0, nifLength - 2); znode.NodeInformationFrame = nodeInfo; // RaiseUpdateParameterEvent(new ZWaveEvent(znode, EventParameter.NodeInfo, Utility.ByteArrayToString(nodeInfo), 0)); RaiseUpdateParameterEvent(new ZWaveEvent(znode, EventParameter.WakeUpNotify, "1", 0)); SaveNodesConfig(); } break; default: Console.WriteLine("\nUNHANDLED Z-Wave REQUEST\n " + Utility.ByteArrayToString(args.Message) + "\n"); break; } break; case MessageType.Response: switch (function) { case Function.DiscoveryNodes: MessageResponseNodeBitMaskHandler(args.Message); break; case Function.GetNodeProtocolInfo: MessageResponseNodeCapabilityHandler(args.Message); break; case Function.RequestNodeInfo: // TODO: shall we do something here? break; case Function.SendData: // TODO: shall we do something here? break; default: Console.WriteLine("\nUNHANDLED Z-Wave RESPONSE\n " + Utility.ByteArrayToString(args.Message) + "\n"); break; } break; default: Console.WriteLine("\nUNHANDLED Z-Wave message TYPE\n " + Utility.ByteArrayToString(args.Message) + "\n"); break; } break; } } catch (Exception ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } }
/// <summary> /// Implements the ResourceLock's OnDone behavior. /// </summary> public void Leave(Boolean write) { if (write) { Debug.Assert((State(m_LockState) == OneManyLockStates.OwnedByWriter) && (NumReadersReading(m_LockState) == 0)); // Pre-condition: Lock's state must be OBW (not Free/OBR/OBRAWP/RFW) // Post-condition: Lock's state must become Free or RFW (the lock is never passed) // Phase 1: Release the lock WakeUp wakeup = DoneWriting(ref m_LockState); // Phase 2: Possibly wake waiters switch (wakeup) { case WakeUp.None: break; case WakeUp.Readers: Int32 numReadersToWake = NumReadersToWake(); if (numReadersToWake > 0) { m_ReadersLock.Release(numReadersToWake); } break; case WakeUp.Writer: Int32 numWritersToWake = NumWritersToWake(); Debug.Assert(numWritersToWake < 2); if (numWritersToWake > 0) { m_WritersLock.Set(); } break; } } else { Debug.Assert((State(m_LockState) == OneManyLockStates.OwnedByReaders) || (State(m_LockState) == OneManyLockStates.OwnedByReadersAndWriterPending)); // Pre-condition: Lock's state must be OBR/OBRAWP (not Free/OBW/RFW) // Post-condition: Lock's state must become unchanged, Free or RFW (the lock is never passed) // Phase 1: Release the lock WakeUp wakeup = DoneReading(ref m_LockState); // Phase 2: Possibly wake a waiting writer switch (wakeup) { case WakeUp.None: break; case WakeUp.Readers: Debug.Assert(false); break; case WakeUp.Writer: Int32 numWritersToWake = NumWritersToWake(); Debug.Assert(numWritersToWake < 2); // Must be 0 or 1 if (numWritersToWake > 0) { m_WritersLock.Set(); } break; } } }
public void SetAlarm(string input) { parse(input); WakeUp.Invoke(this, $"Time is: {hours}:{minutes}"); }