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 + -
显示快捷键?