cmdclassstorage.cs
来自「zwave 无线通讯协议 PC controller 控制器源码」· CS 代码 · 共 553 行
CS
553 行
////////////////////////////////////////////////////////////////////////////////////////////////
//
// #######
// # ## #### ##### ##### ## ## #####
// ## ## ## ## ## ## ## ## ##
// ## # ###### ## ## #### ## ## ####
// ## ## ## ## ## ## ##### ##
// ####### #### ## ## ##### ## #####
// #####
// Z-Wave, the wireless language.
//
// Copyright Zensys A/S, 2003
//
// All Rights Reserved
//
// Description: This source file includes functions for external EEPROM
//
//
// Last Changed By: $Author: jch $
// Revision: $Revision: 1.1 $
// Last Changed: $Date: 2006/03/23 13:37:19 $
//
//////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.Threading;
using System.Collections;
using Zensys.ZWave.Communication;
using Zensys;
namespace ZWavePCController
{
/// <summary>
/// This class handles storage of Command Classes on the Z-Wave module's external EEPROM
/// </summary>
public class CmdClassStorage
{
/// <summary>
/// Executes all elements in Queue and returns true if done
/// </summary>
/// <returns>true if commands could be executed false if not</returns>
/// <summary>
/// Retrieves all the Stored Class table from the EEPROM
/// </summary>
/// <returns></returns>
private void GetStoredClassTable()
{
try
{
byte[] arr = Form1.applicationLayer.ZWaveMemoryGetBuffer(EEPROM_START,(byte)EEP_MAX_CLASSES);
if(arr.Length==storedClasses.Length)
{
storedClasses = arr;
}
}
catch(Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
private void StoreClassIndex(object[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
StoreClassIndex((byte)data[0],(byte)data[1]);
}
/// <summary>
/// Stores a class in the index and EEPROM
/// </summary>
/// <param name="index"></param>
/// <param name="cmdClass"></param>
private void StoreClassIndex(byte index, byte cmdClass)
{
storedClasses[index] = cmdClass;
try
{
Form1.applicationLayer.ZWaveMemoryPutByte(EEPROM_START+index,cmdClass);
}
catch(Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
private void GetStoredMask(object[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
GetStoredMask((byte)data[0]);
}
/// <summary>
/// Retrieves a stored nodemask from the EEPROM
/// </summary>
/// <param name="maskNo">zero based offset of mask to retrieve</param>
private void GetStoredMask(byte maskNo)
{
try
{
byte[] arr = Form1.applicationLayer.ZWaveMemoryGetBuffer(EEP_CLASS_START+(uint)(maskNo*EEP_BITMASK_LENGTH),(byte)EEP_BITMASK_LENGTH);
NodeMask[maskNo].Store(arr);
}
catch(Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
/// <summary>
/// Class that can be used for handling of commandclasses stored in external EEPROM
/// </summary>
public CmdClassStorage()
{
NodeMask = new NodeBitmask[EEP_MAX_CLASSES];
for(int i=0;i<EEP_MAX_CLASSES;i++)
{
NodeMask[i] = new NodeBitmask(EEP_BITMASK_LENGTH);
}
GetStoredClassTable();
for(byte i = 0;i<storedClasses.Length; i++)
{
if(storedClasses[i]!=0)
{
GetStoredMask(i);
}
}
}
/// <summary>
/// Returns wheter a specific commandclass is supported or not
/// </summary>
/// <param name="nodeId"></param>
/// <param name="cmdClass"></param>
/// <returns></returns>
public bool IsSupported(byte nodeId, byte cmdClass)
{
byte i = CmdClassToIndex(cmdClass);
if(i==0xFF)
{
return false;
}
return NodeMask[i].ZWaveNodeMaskNodeIn(nodeId);
}
/// <summary>
/// Returns an array with the supported commandclasses for this nodeID.
/// </summary>
/// <param name="nodeID"></param>
/// <returns>an array with the supported commandclasses for a given NodeID. null if no supported classes</returns>
public byte[] CmdClasses(byte nodeId)
{
byte[] temp = new byte[EEP_MAX_CLASSES];
int n = 0;
for(uint i = 0;i<EEP_MAX_CLASSES;i++)
{
if(storedClasses[i]!=0)
{
if(NodeMask[i].ZWaveNodeMaskNodeIn(nodeId))
{
temp[n++] = storedClasses[i];
}
}
}
if(n!=0)
{
byte[] ret= new byte[n];
while(n>0)
{
ret[n-1] = temp[n-1];
n--;
}
return ret;
}
else
{
return null;
}
}
private void StoreNodeMaskByte(object[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
StoreNodeMaskByte((byte)data[0],(byte)data[1],(bool)data[2]);
}
/// <summary>
/// Stores a single mask byte in external EEPROM and the RAM table
/// </summary>
/// <param name="nodeId">nodeId</param>
/// <param name="index">index of mask</param>
/// <param name="val">true if to write 1 and false to write 0</param>
private void StoreNodeMaskByte(byte nodeId, byte index, bool val)
{
uint adr = EEP_MAX_CLASSES+(uint)(index*EEP_BITMASK_LENGTH);
uint offset = (uint)nodeId >> 3;
if(val)
{
NodeMask[index].ZWaveNodeMaskSetBit(nodeId);
}
else
{
NodeMask[index].ZWaveNodeMaskClearBit(nodeId);
}
byte maskbyte = NodeMask[index].Get(nodeId);
Form1.applicationLayer.ZWaveMemoryPutByte(adr+offset,maskbyte);
}
/// <summary>
/// Clears the user EEPROM data for Cmdclasses
/// </summary>
/// <param name="cb">callback that is called on completion</param>
public void ClearEEPROMData()
{
resetCount = 0;
while(resetCount<EEP_MAX_CLASSES)
{
//Clear bitmasks for each Command Class
NodeMask[resetCount].ZWaveNodeMaskClear();
Form1.applicationLayer.ZWaveMemoryPutBuffer(EEP_MAX_CLASSES+(uint)(resetCount*EEP_BITMASK_LENGTH),NodeMask[resetCount++].Get(),EEP_BITMASK_LENGTH);
}
byte[] clearBuf = new byte[EEP_MAX_CLASSES];
// Clear the stored command class values
Form1.applicationLayer.ZWaveMemoryPutBuffer(EEPROM_START,clearBuf,EEP_MAX_CLASSES);
}
/// <summary>
/// internal callback for Clearing EEPROM
/// </summary>
/// <returns></returns>
private void ClearCmdClass(object[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
ClearCmdClass((byte)data[0]);
}
/// <summary>
/// Clears a whole commandclass from list of supported classes
/// </summary>
/// <param name="index">the commandclass index to clear</param>
/// <param name="cb"></param>
private void ClearCmdClass(byte index)
{
StoreClassIndex(index,0);
{
NodeMask[index].ZWaveNodeMaskClear();
try
{
Form1.applicationLayer.ZWaveMemoryPutBuffer(EEP_MAX_CLASSES+(uint)(index*EEP_BITMASK_LENGTH),NodeMask[index].Get(),EEP_BITMASK_LENGTH);
}
catch(Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
}
/// <summary>
/// Returns Index a given commandclass is stored at
/// </summary>
/// <param name="cmdClass">command class to search for</param>
/// <returns>index or 0xFF if not found</returns>
private byte CmdClassToIndex(byte cmdClass)
{
byte i = 0;
for(i=0;i<EEP_MAX_CLASSES;i++)
{
if(cmdClass==storedClasses[i])
{
break;
}
}
if(i==EEP_MAX_CLASSES)
{
i = 0xFF;
}
return i;
}
/// <summary>
/// Removes a node from all command classes stored
/// </summary>
/// <param name="nodeId"></param>
public void RemoveNode(byte nodeId)
{
uint i = 0;
for(i = 0 ;i<storedClasses.Length; i++)
{
if(storedClasses[i]!=0)
{
ClearNodeFromClass((byte)i, nodeId);
}
}
}
/// <summary>
/// Clears a node from a given mask
/// </summary>
/// <param name="index">commmand class index</param>
/// <param name="nodeId">nodeId</param>
private void ClearNodeFromClass(byte index, byte nodeId)
{
if (NodeMask[index].ZWaveNodeMaskNodeIn(nodeId))
{
StoreNodeMaskByte(nodeId, index, false);
try
{
if(!NodeMask[index].ZWaveNodeMaskBitsIn())
{
//No more nodes of this command class. Free it
StoreClassIndex(index,0);
}
}
catch (System.Exception e)
{
throw new Exception(e.Message);
}
}
}
/// <summary>
/// Stores a command class for a given NodeID
/// </summary>
/// <param name="nodeId"></param>
/// <param name="cmdClass"></param>
/// <returns>true if succesfull false if not</returns>
public bool Store(byte nodeId, byte cmdClass)
{
uint i = 0;
uint firstZero = EEP_MAX_CLASSES;
for(i=0;i<EEP_MAX_CLASSES;i++)
{
if((storedClasses[i]==0)&&(firstZero==EEP_MAX_CLASSES))
{
firstZero = i;
}
if(storedClasses[i]==cmdClass)
{
break;
}
}
if(i<EEP_MAX_CLASSES)
{
//EEPROM already have class update and store this nodeID
StoreNodeMaskByte(nodeId, (byte)i, true);
}
else
{
//New Cmdclass store it if we have room
if(firstZero<EEP_MAX_CLASSES)
{
StoreClassIndex((byte)firstZero,cmdClass);
NodeMask[firstZero].ZWaveNodeMaskClear();
StoreNodeMaskByte(nodeId, (byte)firstZero, true);
}
else
{
//No more room for Cmd Classes
return false;
}
}
return true;
}
/// <summary>
/// Returns true if Queue is empty
/// </summary>
public bool QueueEmpty
{
get
{
return (moduleQueue.Count==0);
}
}
#region Fields
/// <summary>
/// Writes and reads to/from EEPROM will end up in this queue if IsReady is false
/// It should be flushed by Application
/// </summary>
private Queue moduleQueue = new Queue();
private const uint EEPROM_START = 0x00;
private const uint EEP_MAX_CLASSES = 32 + EEPROM_START;
private const uint EEP_CLASS_START = EEP_MAX_CLASSES;
private const byte EEP_BITMASK_LENGTH = 29;
private delegate void QueueDelegate(object[] data);
private delegate void VoidQueueDelegate();
private byte[] storedClasses = new byte[EEP_MAX_CLASSES];
private byte resetCount;
private NodeBitmask[] NodeMask;
#endregion Fields
} //End CmdClassStorage
#region NodeBitmask
/// <summary>
/// Nodemask handling class
/// </summary>
public class NodeBitmask
{
/// <summary>
/// Creates a nodemask object
/// </summary>
/// <param name="length">length of nodemask (number of ids/8)</param>
public NodeBitmask(byte length)
{
if (length > 0)
{
mask = new byte[length];
// maxNodeID = length*8;
}
}
/// <summary>
/// Gets the nodemask as an bit array
/// </summary>
/// <returns></returns>
public byte[] Get()
{
return mask;
}
/// <summary>
/// Returns the bitMask for the given NodeId
/// </summary>
/// <param name="nodeId"></param>
/// <returns></returns>
public byte Get(byte nodeId)
{
return mask[nodeId >> 3];
}
/// <summary>
/// Stores an entire array
/// </summary>
/// <param name="arr"></param>
public void Store(byte[] array)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if(mask==null)
{
mask = new byte[array.Length];
}
for(int i=0;i<mask.Length;i++)
{
mask[i] = array[i];
}
}
/// <summary>
/// Set the bit corresponding to the nodeID supplied
/// </summary>
/// <param name="nodeId"></param>
public void ZWaveNodeMaskSetBit(byte nodeId)
{
if (nodeId < 1)
{
return;
}
nodeId--;
mask[nodeId >> 3] |= (byte)(0x1 << (nodeId & 7));
}
/// <summary>
/// Clears the bit corresponding to then nodeID supplied
/// </summary>
/// <param name="nodeId"></param>
public void ZWaveNodeMaskClearBit(byte nodeId)
{
if (nodeId < 1)
{
return;
}
nodeId--;
mask[nodeId >> 3] &= (byte)~(0x1 << (nodeId & 7));
}
/// <summary>
/// Checks if the bit corresponding to the node ID is set
/// </summary>
/// <param name="nodeId"></param>
/// <returns>true if bit is set</returns>
public bool ZWaveNodeMaskNodeIn(byte nodeId)
{
if (nodeId < 1)
{
return false;
}
nodeId--;
if ((((mask[(nodeId >> 3)]) >> (byte)(nodeId & 7)) & (byte)0x01) != 0)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Returns true if any bits in mask
/// </summary>
/// <returns>true if bits set, false if not</returns>
public bool ZWaveNodeMaskBitsIn()
{
if(mask!=null)
{
for(int i=0;i<mask.Length;i++)
{
if(mask[i]!=0)
{
return true;
}
}
}
return false;
}
/// <summary>
/// Clears the nodemask
/// </summary>
public void ZWaveNodeMaskClear()
{
if(mask!=null)
{
for(int i = 0;i<mask.Length;i++)
{
mask[i] = 0;
}
}
}
private byte[] mask;
// private int maxNodeID;
}//Class BitMask
#endregion NodeBitmask
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?