Package com.francetelecom.m2m.gateway.service.machine.zigbee.common

Source Code of com.francetelecom.m2m.gateway.service.machine.zigbee.common.DataType

/*
* Created on 28 juin 2007
*
* Projet M2MMachine
*/
package com.francetelecom.m2m.gateway.service.machine.zigbee.common;

import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.NoSuchElementException;

import org.osgi.service.zigbee.descriptions.ZigBeeDataTypeDescription;

import com.francetelecom.m2m.gateway.bundle.machine.common.Element;

/**
* @author Fabrice Blache
*
*/
public class DataType {
 
     
  /**
   * No data type The no data type is a special type to represent an attribute
   * with no associated data.
   */
  public static final short NO_DATA = 0x00;

  /**
   * Boolean The Boolean type represents a logical value, either TRUE (0x00)
   * or FALSE (0x01). The value 0xff represents an invalid value of this type.
   * All other values of this type are forbidden
   */
  public static final short GENERAL_DATA_8 = 0x08;

  public static final short GENERAL_DATA_16 = 0x09;

  public static final short GENERAL_DATA_24 = 0x0a;

  public static final short GENERAL_DATA_32 = 0x0b;
 
  public static final short GENERAL_DATA_40 = 0x0c;

  public static final short GENERAL_DATA_48 = 0x0d;

  public static final short GENERAL_DATA_56 = 0x0e;
 
  public static final short GENERAL_DATA_64 = 0x0f;


  /**
   * Boolean The Boolean type represents a logical value, either TRUE (0x00)
   * or FALSE (0x01). The value 0xff represents an invalid value of this type.
   * All other values of this type are forbidden.
   */
  public static final short BOOLEAN = 0x10;
 
  /**
   * Bitmap (8-bit, 16-bit, 24-bit and 32-bit) The Bitmap type holds 8, 16, 24
   * or 32 logical values, one per bit, depending on its length. There is no
   * value to represent an invalid value of this type.
   */
  public static final short BITMAP_8 = 0x18;

  public static final short BITMAP_16 = 0x19;

  public static final short BITMAP_24 = 0x1a;

  public static final short BITMAP_32 = 0x1b;
 
  public static final short BITMAP_40 = 0x1c;

  public static final short BITMAP_48 = 0x1d;

  public static final short BITMAP_56 = 0x1e;

  public static final short BITMAP_64 = 0x1f;


  /**
   * Unsigned integer (8-bit, 16-bit, 24-bit and 32-bit) This type represents
   * an unsigned integer with a decimal range of 0 to 28-1, 0 to 216-1, 0 to
   * 224-1, or 0 to 232-1, depending on its length. The values that represents
   * an invalid value of this type are 0xff, 0xffff, 0xffffff and 0xffffffff
   * respectively.
   */
  public static final short UNSIGNED_INTEGER_8 = 0x20;

  public static final short UNSIGNED_INTEGER_16 = 0x21;

  public static final short UNSIGNED_INTEGER_24 = 0x22;

  public static final short UNSIGNED_INTEGER_32 = 0x23;
 
  public static final short UNSIGNED_INTEGER_40 = 0x24;
 
  public static final short UNSIGNED_INTEGER_48 = 0x25;
 
  public static final short UNSIGNED_INTEGER_56 = 0x26;
 
  public static final short UNSIGNED_INTEGER_64 = 0x27;

  /**
   * Signed integer (8-bit, 16-bit, 24-bit and 32-bit) This type represents a
   * signed integer with a decimal range of -(27-1) to 27-1, -(215-1) to
   * 215-1, -(223-1) to 223-1, or -(231-1) to 231-1, depending on its length.
   * The values that represents an invalid value of this type are 0x80,
   * 0x8000, 0x800000 and 0x80000000 respectively.
   */
  public static final short SIGNED_INTEGER_8 = 0x28;

  public static final short SIGNED_INTEGER_16 = 0x29;

  public static final short SIGNED_INTEGER_24 = 0x2a;

  public static final short SIGNED_INTEGER_32 = 0x2b;
 
  public static final short SIGNED_INTEGER_40 = 0x2c;
 
  public static final short SIGNED_INTEGER_48 = 0x2d;
 
  public static final short SIGNED_INTEGER_56 = 0x2e;
 
  public static final short SIGNED_INTEGER_64 = 0x2f                                                                                                                                                                                                    ;

  /**
   * Enumeration (8-bit) The Enumeration type represents an index into a
   * lookup table to determine the final value. The value 0xff represents an
   * invalid value of this type
   */
  public static final short ENUMERATION_8 = 0x30;

  public static final short ENUMERATION_16 = 0x31;

  /**
   * Semi-precision The ZigBee semi-precision number format is based on the
   * IEEE 754 standard for binary floating-point arithmetic [R11]. This number
   * format should be used very sparingly, when absolutely necessary, keeping
   * in mind the code and processing required supporting it. The value is
   * calculated as: Value = -1Sign * (Hidden + Mantissa/1024) * 2
   * (Exponent-15)
   */
  public static final short FLOATING_SEMI = 0x38;

  /**
   * Single precision The format of the single precision data type is based on
   * the IEEE 754 standard for binary floating-point arithmetic [R11]. This
   * number format should be used very sparingly, when absolutely necessary,
   * keeping in mind the code and processing required supporting it. The
   * format and interpretation of values of this data type follow the same
   * rules as given for the semi-precision data type, but with shorter
   * sub-fields, as follows. Length of mantissa = 23 bits, length of exponent
   * = 8 bits For further details, see [R11]. = 0x43;
   */
  public static final short FLOATING_SINGLE = 0x39;

  /**
   * Double precision The format of the double precision data type is based on
   * the IEEE 754 standard for binary floating-point arithmetic [R11]. This
   * number format should be used very sparingly, when absolutely necessary,
   * keeping in mind the code and processing required supporting it. The
   * format and interpretation of values of this data type follow the same
   * rules as given for the semi-precision data type, but with shorter
   * sub-fields, as follows. Length of mantissa = 52 bits, length of exponent
   * = 11 bits For further details, see [R11].
   */
  public static final short FLOATING_DOUBLE = 0x3a;

  /**
   * The octet string data type contains data in an application-defined
   * format, not defined in this specification. The octet string data type
   * shall be formatted as illustrated in Error! Reference source not found..
   *
   * Octets: 1 Variable Octet count Octet data Figure 27 - Format of the octet
   * string type The octet count sub-field is one octet in length and
   * specifies the number of octets contained in the octet data sub-field.
   * Setting this sub-field to 0x00 represents an octet string with no octet
   * data (an "empty string"). Setting this sub-field to 0xff represents an
   * invalid octet string value. In both cases the octet data sub-field has
   * zero length. The octet data sub-field is n octets in length, where n is
   * the value of the octet count sub-field. This sub-field contains the
   * application-defined data.
   */
  public static final short OCTET_STRING = 0x41;

  /**
   * Character string The character string data type contains data octets
   * encoding characters according to the language and character set field of
   * the complex descriptor. The character string data type shall be formatted
   * as illustrated in Figure 28.
   *
   * Octets: 1 Variable Character count Character data
   *
   * The character count sub-field is one octet in length and specifies the
   * number of characters, encoded according to the language and character set
   * field of the complex descriptor (see [R2]), contained in the character
   * data sub-field. Setting this sub-field to 0x00 represents a character
   * string with no character data (an "empty string"). Setting this sub-field
   * to 0xff represents an invalid character string value. In both cases the
   * character data sub-field has zero length. The character data sub-field is
   * e*n octets in length, where e is the size of the character, as specified
   * by the language and character set field of the complex descriptor, and n
   * is the value of the character count sub-field. This sub-field contains
   * the encoded characters that comprise the desired character string. A
   * character string with no contents, i.e. with the character count
   * sub-field equal to 0x00 and a zero length character data sub-field, shall
   * be referred to as an 'empty string'.
   *
   */
  public static final short CHARACTER_STRING = 0x42;
 
  public static final short LONG_OCTET_STRING = 0x43;
 
  public static final short LONG_CHARACTER_STRING = 0x44;
 
  public static final short ARRAY = 0x48;
 
  public static final short STRUCTURE = 0x4c;
 
  public static final short SET = 0x50;
 
  public static final short BAG = 0x51;

  /**
   * Time of day The Time of day data type shall be formatted as illustrated
   * in Figure 29.
   *
   * Octets: 1 1 1 1 Hours Minutes Seconds Hundredths
   *
   * The hours subfield represents hours according to a 24 hour clock. The
   * range is from 0 to 23. The minutes subfield represents minutes of the
   * current hour. The range is from 0 to 59. The seconds subfield represents
   * seconds of the current minute. The range is from 0 to 59. The hundredths
   * subfield represents 100ths of the current second. The range is from 0 to
   * 99. A value of 0xff in any subfield indicates an unused subfield. If all
   * subfields have the value 0xff, this indicates an invalid or 'don't care'
   * value of the data type.
   */
  public static final short TIME_OF_DAY = 0xe0;
 
  /**
   * Date The Time of day data type shall be formatted as illustrated in
   * Figure 30. Octets: 1 1 1 1 Year - 1900 Month Day of month Day of week
   *
   * The year - 1900 subfield has a range of 0 to 255, representing years from
   * 1900 to 2155. The month subfield has a range of 1 to 12, representing
   * January to December. The day of month subfield has a range of 1 to 31.
   * Note that values in the range 29 to 31 may be invalid, depending on the
   * month and year. The day of week subfield has a range of 1 to 7,
   * representing Monday to Sunday. A value of 0xff in any subfield indicates
   * an unused subfield. If all subfields have the value 0xff, this indicates
   * an invalid or 'don't care' value of the data type.
   */
  public static final short DATE = 0xe1;
 
  public static final short UTC_TIME = 0xe2;

  public static final short CLUSTER_ID = 0xe8;

  public static final short ATTRIBUTE_ID = 0xe9;

  /**
   * BACnet OID (Object Identifier) The BACnet OID data type is included to
   * allow interworking with BACnet (see [R12]). The format is described in
   * the referenced standard.
   */
  public static final short BACNET_OID = 0xea;

  public static final short IEEE_ADDRESS = 0xf0;

  // Pour inverser les octets
  protected static final boolean RETOURNER = true;
 
 
 

  /**
   * Indique s'il s'agit d'un type analogique ou d'un type discret
   *
   * @param type
   * @return true si analog, false si discret
   */
  public static boolean isAnalogAttribute(short type) {

    if (type == UNSIGNED_INTEGER_8 || type == UNSIGNED_INTEGER_16 || type == UNSIGNED_INTEGER_24 || type == UNSIGNED_INTEGER_32 || type == UNSIGNED_INTEGER_40 || type == UNSIGNED_INTEGER_48 || type == UNSIGNED_INTEGER_56 || type == UNSIGNED_INTEGER_64 ||
        type == SIGNED_INTEGER_8 || type == SIGNED_INTEGER_16 || type == SIGNED_INTEGER_24 || type == SIGNED_INTEGER_32 || type == SIGNED_INTEGER_40 || type == SIGNED_INTEGER_48 || type == SIGNED_INTEGER_56 || type == SIGNED_INTEGER_64 ||
        type == FLOATING_SEMI || type == FLOATING_SINGLE || type == FLOATING_DOUBLE || type == TIME_OF_DAY || type == DATE || type == UTC_TIME ) {
      return true;
    } else {
      return false;
    }
  }

  public static boolean isDiscretAttribute(short type) {

    if (type == GENERAL_DATA_8 || type == GENERAL_DATA_16 || type == GENERAL_DATA_24 || type == GENERAL_DATA_32 || type == GENERAL_DATA_40 || type == GENERAL_DATA_48 || type == GENERAL_DATA_56 || type == GENERAL_DATA_64 || 
        type == BOOLEAN || type == BITMAP_8 || type == BITMAP_16 || type == BITMAP_24 || type == BITMAP_32 || type == BITMAP_40 || type == BITMAP_48 || type == BITMAP_56 || type == BITMAP_64 ||
        type == ENUMERATION_8 || type == ENUMERATION_16 || type == ATTRIBUTE_ID || type == BACNET_OID || type == IEEE_ADDRESS || type == OCTET_STRING || type == CHARACTER_STRING ||type == LONG_OCTET_STRING ||type == LONG_CHARACTER_STRING ) {     
      return true;
    } else {
      return false;
    }
  }

  public static boolean isValideType(short type) throws IllegalArgumentException {
    boolean retour = false;

    switch (type & 0xff) {
    case GENERAL_DATA_8:
    case GENERAL_DATA_16:
    case GENERAL_DATA_24:
    case GENERAL_DATA_32:
    case GENERAL_DATA_40:
    case GENERAL_DATA_48:
    case GENERAL_DATA_56:
    case GENERAL_DATA_64:
    case BOOLEAN:
    case BITMAP_8:
    case BITMAP_16:
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:
    case BITMAP_48:
    case BITMAP_56:
    case BITMAP_64:
    case UNSIGNED_INTEGER_8:
    case UNSIGNED_INTEGER_16:
    case UNSIGNED_INTEGER_24:
    case UNSIGNED_INTEGER_32:
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:
    case UNSIGNED_INTEGER_64:     
    case SIGNED_INTEGER_8:
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:
    case SIGNED_INTEGER_56:
    case SIGNED_INTEGER_64:     
    case ENUMERATION_8:
    case ENUMERATION_16:
    case FLOATING_SEMI:
    case FLOATING_SINGLE:
    case FLOATING_DOUBLE:
    case OCTET_STRING:     
    case CHARACTER_STRING:     
    case LONG_OCTET_STRING:         
    case LONG_CHARACTER_STRING:     
    case ARRAY:     
    case STRUCTURE:     
    case SET:     
    case BAG:
    case TIME_OF_DAY:
    case DATE:
    case UTC_TIME:
    case CLUSTER_ID:
    case ATTRIBUTE_ID:
    case BACNET_OID:
    case IEEE_ADDRESS:
      retour = true;
      break;
    default:
      retour = false;
      break;
    }
    return retour;
  }

  /**
   * get data type in String form
   * @param type
   * @return type name
   * @throws IllegalArgumentException if unknown type
   */
   public static String type2StringConstante(short type) throws IllegalArgumentException {
      String retour = null;
          
      switch (type & 0xff) {
      case GENERAL_DATA_8:
        retour = "GENERAL_DATA_8";
        break;
      case GENERAL_DATA_16:
        retour = "GENERAL_DATA_16";
        break;
      case GENERAL_DATA_24:
        retour = "GENERAL_DATA_24";
        break;
      case GENERAL_DATA_32:
        retour = "GENERAL_DATA_32";
        break;
      case GENERAL_DATA_40:
        retour = "GENERAL_DATA_40";
        break;
      case GENERAL_DATA_48:
        retour = "GENERAL_DATA_48";
        break;
      case GENERAL_DATA_56:
        retour = "GENERAL_DATA_56";
        break;
      case GENERAL_DATA_64:
        retour = "GENERAL_DATA_64";
        break;
      case BOOLEAN:
        retour = "BOOLEAN";
        break;
      case BITMAP_8:
        retour = "BITMAP_8";
        break;
      case BITMAP_16:
        retour = "BITMAP_16";
        break;
      case BITMAP_24:
        retour = "BITMAP_24";
        break;
      case BITMAP_32:
        retour = "BITMAP_32";
        break;
      case BITMAP_40:
        retour = "BITMAP_40";
        break;
      case BITMAP_48:
        retour = "BITMAP_48";
        break;
      case BITMAP_56:
        retour = "BITMAP_56";
        break;
      case BITMAP_64:
        retour = "BITMAP_64";
        break;
      case UNSIGNED_INTEGER_8:
        retour = "UNSIGNED_INTEGER_8";
        break;
      case UNSIGNED_INTEGER_16:
        retour = "UNSIGNED_INTEGER_16";
        break;
      case UNSIGNED_INTEGER_24:
        retour = "UNSIGNED_INTEGER_24";
        break;
      case UNSIGNED_INTEGER_32:
        retour = "UNSIGNED_INTEGER_32";
        break;
      case UNSIGNED_INTEGER_40:
        retour = "UNSIGNED_INTEGER_40";
        break;
      case UNSIGNED_INTEGER_48:
        retour = "UNSIGNED_INTEGER_48";
        break;
      case UNSIGNED_INTEGER_56:
        retour = "UNSIGNED_INTEGER_56";
        break;
      case UNSIGNED_INTEGER_64:    
        retour = "UNSIGNED_INTEGER_64";
        break;
      case SIGNED_INTEGER_8:
        retour = "SIGNED_INTEGER_8";
        break;
      case SIGNED_INTEGER_16:
        retour = "SIGNED_INTEGER_16";
        break;
      case SIGNED_INTEGER_24:
        retour = "SIGNED_INTEGER_24";
        break;
      case SIGNED_INTEGER_32:
        retour = "SIGNED_INTEGER_32";
        break;
      case SIGNED_INTEGER_40:
        retour = "SIGNED_INTEGER_40";
        break;
      case SIGNED_INTEGER_48:
        retour = "SIGNED_INTEGER_48";
        break;
      case SIGNED_INTEGER_56:
        retour = "SIGNED_INTEGER_56";
        break;
      case SIGNED_INTEGER_64:    
        retour = "SIGNED_INTEGER_64";
        break;
      case ENUMERATION_8:
        retour = "ENUMERATION_8";
        break;
      case ENUMERATION_16:
        retour = "ENUMERATION_16";
        break;
      case FLOATING_SEMI:
        retour = "FLOATING_SEMI";
        break;
      case FLOATING_SINGLE:
        retour = "FLOATING_SINGLE";
        break;
      case FLOATING_DOUBLE:
        retour = "FLOATING_DOUBLE";
        break;
      case OCTET_STRING:     
        retour = "OCTET_STRING";
        break;
      case CHARACTER_STRING:     
        retour = "CHARACTER_STRING";
        break;
      case LONG_OCTET_STRING:        
        retour = "LONG_OCTET_STRING";
        break;
      case LONG_CHARACTER_STRING:    
        retour = "LONG_CHARACTER_STRING";
        break;
      case ARRAY:    
        retour = "ARRAY";
        break;
      case STRUCTURE:    
        retour = "STRUCTURE";
        break;
      case SET:    
        retour = "SET";
        break;
      case BAG:
        retour = "BAG";
        break;
      case TIME_OF_DAY:
        retour = "TIME_OF_DAY";
        break;
      case DATE:
        retour = "DATE";
        break;
      case UTC_TIME:
        retour = "UTC_TIME";
        break;
      case CLUSTER_ID:
        retour = "CLUSTER_ID";
        break;
      case ATTRIBUTE_ID:
        retour = "ATTRIBUTE_ID";
        break;
      case BACNET_OID:
        retour = "BACNET_OID";
        break;
      case IEEE_ADDRESS:
        retour = "IEEE_ADDRESS";
        break;
      default:
        throw new IllegalArgumentException();
      }
     
      return retour;
    }

   /**
     * get data type in String form
     * @param type
     * @return type name
     * @throws IllegalArgumentException if unknown type
     */
     public static String type2LiteralStringLong(short type) throws IllegalArgumentException {
        String retour = null;

        switch (type & 0xff) {
        case GENERAL_DATA_8:
          retour = "8-bit data";
          break;
        case GENERAL_DATA_16:
          retour = "16-bit data";
          break;
        case GENERAL_DATA_24:
          retour = "24-bit data";
          break;
        case GENERAL_DATA_32:
          retour = "32-bit data";
          break;
        case GENERAL_DATA_40:
          retour = "40-bit data";
          break;
        case GENERAL_DATA_48:
          retour = "48-bit data";
          break;
        case GENERAL_DATA_56:
          retour = "56-bit data";
          break;
        case GENERAL_DATA_64:
          retour = "64-bit data";
          break;
        case BOOLEAN:
          retour = "Boolean";
          break;
        case BITMAP_8:
          retour = "8-bit bitmap";
          break;
        case BITMAP_16:
          retour = "16-bit bitmap";
          break;
        case BITMAP_24:
          retour = "24-bit bitmap";
          break;
        case BITMAP_32:
          retour = "32-bit bitmap";
          break;
        case BITMAP_40:
          retour = "40-bit bitmap";
          break;
        case BITMAP_48:
          retour = "48-bit bitmap";
          break;
        case BITMAP_56:
          retour = "56-bit bitmap";
          break;
        case BITMAP_64:
          retour = "64-bit bitmap";
          break;
        case UNSIGNED_INTEGER_8:
          retour = "Unsigned 8-bit integer";
          break;
        case UNSIGNED_INTEGER_16:
          retour = "Unsigned 16-bit integer";
          break;
        case UNSIGNED_INTEGER_24:
          retour = "Unsigned 24-bit integer";
          break;
        case UNSIGNED_INTEGER_32:
          retour = "Unsigned 32-bit integer";
          break;
        case UNSIGNED_INTEGER_40:
          retour = "Unsigned 40-bit integer";
          break;
        case UNSIGNED_INTEGER_48:
          retour = "Unsigned 48-bit integer";
          break;
        case UNSIGNED_INTEGER_56:
          retour = "Unsigned 56-bit integer";
          break;
        case UNSIGNED_INTEGER_64:    
          retour = "Unsigned 64-bit integer";
          break;
        case SIGNED_INTEGER_8:
          retour = "Signed 8-bit integer";
          break;
        case SIGNED_INTEGER_16:
          retour = "Signed 15-bit integer";
          break;
        case SIGNED_INTEGER_24:
          retour = "Signed 24-bit integer";
          break;
        case SIGNED_INTEGER_32:
          retour = "Signed 32-bit integer";
          break;
        case SIGNED_INTEGER_40:
          retour = "Signed 40-bit integer";
          break;
        case SIGNED_INTEGER_48:
          retour = "Signed 48-bit integer";
          break;
        case SIGNED_INTEGER_56:
          retour = "Signed 56-bit integer";
          break;
        case SIGNED_INTEGER_64:    
          retour = "Signed 64-bit integer";
          break;
        case ENUMERATION_8:
          retour = "8-bit ennumeration";
          break;
        case ENUMERATION_16:
          retour = "16-bit ennumeration";
          break;
        case FLOATING_SEMI:
          retour = "Semi-precision";
          break;
        case FLOATING_SINGLE:
          retour = "Single precision";
          break;
        case FLOATING_DOUBLE:
          retour = "double presision";
          break;
        case OCTET_STRING:     
          retour = "Octet string";
          break;
        case CHARACTER_STRING:     
          retour = "Character string";
          break;
        case LONG_OCTET_STRING:        
          retour = "Long octet string";
          break;
        case LONG_CHARACTER_STRING:    
          retour = "Long character string";
          break;
        case ARRAY:    
          retour = "array";
          break;
        case STRUCTURE:    
          retour = "Structure";
          break;
        case SET:    
          retour = "Set";
          break;
        case BAG:
          retour = "Bag";
          break;
        case TIME_OF_DAY:
          retour = "Time of day";
          break;
        case DATE:
          retour = "Date";
          break;
        case UTC_TIME:
          retour = "UTCTime";
          break;
        case CLUSTER_ID:
          retour = "Cluster ID";
          break;
        case ATTRIBUTE_ID:
          retour = "Attribute ID";
          break;
        case BACNET_OID:
          retour = "BACnet OID";
          break;
        case IEEE_ADDRESS:
          retour = "IEEE address";
          break;
        default:
          throw new IllegalArgumentException("type = " + type);
        }
       
        return retour;
   }
    
    
     public static String type2LiteralStringShort(short type) throws IllegalArgumentException {       
         return type2LiteralStringLong(type).replaceAll("[0-9]{1,2}-bit", "").replace("  ", " ").trim();              
   }
    
    
     public static short typeString2Type(String type) throws IllegalArgumentException {
       
         if(type==null || type.length()<3 ||  type.length()>(30+"List of".length()) )
           throw new IllegalArgumentException("StringType2Type : Argument invalide ");
      
        if(type.matches(".*(?i)data.*")){
          int nbBit = Integer.parseInt(type.replaceAll("[a-zA-Z\\-]", "").trim());
          return (short)(GENERAL_DATA_8 + (nbBit/8)-1);
        }
        if(type.matches(".*(?i)Boolean.*")){
          return (short)(BOOLEAN );
        }
        if(type.matches(".*(?i)bitmap.*")){
          int nbBit = Integer.parseInt(type.replaceAll("[a-zA-Z\\-]", "").trim());
          return (short)(BITMAP_8 + (nbBit/8)-1);
        }
        if(type.matches(".*(?i)Unsigned.*")){
          int nbBit = Integer.parseInt(type.replaceAll("[a-zA-Z\\-]", "").trim());
          return (short)(UNSIGNED_INTEGER_8 + (nbBit/8)-1);
        }
        if(type.matches(".*(?i)signed.*")){
          int nbBit = Integer.parseInt(type.replaceAll("[a-zA-Z\\-]", "").trim());
          return (short)(SIGNED_INTEGER_8 + (nbBit/8)-1);
        }
        if(type.matches(".*(?i)enumeration.*")){
          int nbBit = Integer.parseInt(type.replaceAll("[a-zA-Z\\-]", "").trim());
          return (short)(ENUMERATION_8 + (nbBit/8)-1);
        }
        if(type.matches(".*(?i)Semi.*")){
          return (short)(FLOATING_SEMI );
        }
        if(type.matches(".*(?i)Single.*")){
          return (short)(FLOATING_SINGLE );
        }
        if(type.matches(".*(?i)double.*")){
          return (short)(FLOATING_DOUBLE );
        }
        if(type.matches(".*(?i)Long octet.*")){
          return (short)(LONG_OCTET_STRING );
        }
        if(type.matches(".*(?i)octet.*")){
          return (short)(OCTET_STRING );
        }
        if(type.matches(".*(?i)Long character.*")){
          return (short)(LONG_CHARACTER_STRING );
        }
        if(type.matches(".*(?i)character.*")){
          return (short)(CHARACTER_STRING );
        }
        if(type.matches(".*(?i)array.*")){
          return (short)(ARRAY );
        }
        if(type.matches(".*(?i)set.*")){
          return (short)(SET );
        }
        if(type.matches(".*(?i)bag.*")){
          return (short)(BAG );
        }
        if(type.matches(".*(?i)Structure.*")){
          return (short)(STRUCTURE );
        }
        if(type.matches(".*(?i)Date.*")){
          return (short)(DATE );
        }
        if(type.matches(".*(?i)UTCTime.*")){
          return (short)(UTC_TIME );
        }
        if(type.matches(".*(?i)Time.*")){
          return (short)(TIME_OF_DAY );
        }
        if(type.matches(".*(?i)Cluster.*")){
          return (short)(CLUSTER_ID )
        }
        if(type.matches(".*(?i)Attribute.*")){
          return (short)(ATTRIBUTE_ID );
        }
        if(type.matches(".*(?i)IEEE.*")){
          return (short)(IEEE_ADDRESS );
        }
        if(type.matches(".*(?i)BACnet.*")){
          return (short)(BACNET_OID );
        }

        return (short)-1;
  }
  
  /**
   * Renvoie la taille des donnees selon le type et 0 si elle ne peut etre
   * determinee
   *
   * @param type
   * @return taille en octet
   */
  public static short getBytesLength(short type) throws IllegalArgumentException, NoSuchElementException {
    short retour = 0;

    switch (type) {
    case GENERAL_DATA_8:
      retour = 1;
      break;
    case GENERAL_DATA_16:
      retour = 2;
      break;
    case GENERAL_DATA_24:
      retour = 3;
      break;
    case GENERAL_DATA_32:
      retour = 4;
      break;
    case GENERAL_DATA_40:
      retour = 5;
      break;
    case GENERAL_DATA_48:
      retour = 6;
      break;
    case GENERAL_DATA_56:
      retour = 7;
      break;
    case GENERAL_DATA_64:
      retour = 8;
      break;
     
    case BOOLEAN:
      retour = 1;
      break;

    case BITMAP_8:
      retour = 1;
      break;
    case BITMAP_16:
      retour = 2;
      break;
    case BITMAP_24:
      retour = 3;
      break;
    case BITMAP_32:
      retour = 4;
      break;
    case BITMAP_40:
      retour = 5;
      break;
    case BITMAP_48:
      retour = 6;
      break;
    case BITMAP_56:
      retour = 7;
      break;
    case BITMAP_64:
      retour = 8;
      break;
     

    case UNSIGNED_INTEGER_8:
      retour = 1;
      break;
    case UNSIGNED_INTEGER_16:
      retour = 2;
      break;
    case UNSIGNED_INTEGER_24:
      retour = 3;
      break;
    case UNSIGNED_INTEGER_32:
      retour = 4;
      break;
    case UNSIGNED_INTEGER_40:
      retour = 5;
      break;
    case UNSIGNED_INTEGER_48:
      retour = 6;
      break;
    case UNSIGNED_INTEGER_56:
      retour = 7;
      break;
    case UNSIGNED_INTEGER_64:
      retour = 8;
      break

    case SIGNED_INTEGER_8:
      retour = 1;
      break;
    case SIGNED_INTEGER_16:
      retour = 2;
      break;
    case SIGNED_INTEGER_24:
      retour = 3;
      break;
    case SIGNED_INTEGER_32:
      retour = 4;
      break;
    case SIGNED_INTEGER_40:
      retour = 5;
      break;
    case SIGNED_INTEGER_48:
      retour = 6;
      break;
    case SIGNED_INTEGER_56:
      retour = 7;
      break;
    case SIGNED_INTEGER_64:
      retour = 8;
      break;

    case ENUMERATION_8:
      retour = 1;
      break;
    case ENUMERATION_16:
      retour = 2;
      break;

    case FLOATING_SEMI:
      retour = 2;
      break;
    case FLOATING_SINGLE:
      retour = 4;
      break;
    case FLOATING_DOUBLE:
      retour = 8;
      break;

    case TIME_OF_DAY:
      retour = 4;
      break;
    case DATE:
      retour = 4;
      break;
    case UTC_TIME:
      retour = 4;
      break
     
    case CLUSTER_ID:
      retour = 2;
      break;
    case ATTRIBUTE_ID:
      retour = 2;
      break;
    case BACNET_OID:
      retour = 4;
      break;
    case IEEE_ADDRESS:
      retour = 8;
      break;
     
     
     
    case
      CHARACTER_STRING:
    case       
      LONG_CHARACTER_STRING:
    case       
      OCTET_STRING:
    case       
      LONG_OCTET_STRING:       
    case       
      ARRAY:       
    case       
      SET:       
    case       
      STRUCTURE:       
    case       
      BAG:       
      throw new NoSuchElementException("Le type est de taille variable ");
     
    default:
      throw new IllegalArgumentException("Type inconnu pour la determination de taille. Type = " + Integer.toHexString(type) );
    }

    return retour;

  }

  /**
   * Renvoie directement le donnee invalide pour le type definit ou rien
   *
   * @param type
   * @return Invalide Number
   */
  public static String getInvalideNumber2String(short type, int base) {
    String retour = "";

    /* Base 2 ou 16 */
    if (base != 16 && base != 2)
      throw new NumberFormatException("Base non supportee");

    switch (type) {

    case BOOLEAN:
      retour = "ff";
      break;

    case UNSIGNED_INTEGER_8:
      retour = "ff";
      break;
    case UNSIGNED_INTEGER_16:
      retour = "ffff";
      break;
    case UNSIGNED_INTEGER_24:
      retour = "ffffff";
      break;
    case UNSIGNED_INTEGER_32:
      retour = "ffffffff";
      break;
    case UNSIGNED_INTEGER_40:
      retour = "ffffffffff";
      break;
    case UNSIGNED_INTEGER_48:
      retour = "ffffffffffff";
      break;
    case UNSIGNED_INTEGER_56:
      retour = "ffffffffffffff";
      break;
    case UNSIGNED_INTEGER_64:
      retour = "ffffffffffffffff";
      break;

    case SIGNED_INTEGER_8:
      retour = "80";
      break;
    case SIGNED_INTEGER_16:
      retour = "8000";
      break;
    case SIGNED_INTEGER_24:
      retour = "800000";
      break;
    case SIGNED_INTEGER_32:
      retour = "80000000";
      break;
    case SIGNED_INTEGER_40:
      retour = "8000000000";
      break;
    case SIGNED_INTEGER_48:
      retour = "800000000000";
      break;
    case SIGNED_INTEGER_56:
      retour = "80000000000000";
      break;
    case SIGNED_INTEGER_64:
      retour = "8000000000000000";
      break;     
     

    case ENUMERATION_8:
      retour = "ff";
      break;
    case ENUMERATION_16:
      retour = "ffff";
      break;

    case TIME_OF_DAY:
      retour = "ffffffff";
      break;
    case DATE:
      retour = "ffffffff";
      break;
    case UTC_TIME:
      retour = "ffffffff";
      break;     
    case CLUSTER_ID:
      retour = "ffff";
      break;
    case ATTRIBUTE_ID:
      retour = "ffff";
      break;
    case BACNET_OID:
      retour = "ffffffff";
      break;
    case IEEE_ADDRESS:
      retour = "ffffffffffffffff";
      break;
    default:
      retour = "";
    }

    // On peut faire autrement ...
    if (base == 2) {
      String newRetour = "";
      for (int i = 0; i < retour.length(); i++) {
        if (retour.substring(i, i + 1).equals("f")) {
          newRetour = newRetour + "11111111";
        } else {
          if (retour.substring(i, i + 1).equals("8")) {
            newRetour = newRetour + "10000000";
          } else {
            newRetour = newRetour + "00000000";
          }
        }
      }
      retour = newRetour;
    }
    return retour;
  }

  /**
   * Renvoie directement le donnee invalide pour le type definit ou rien
   *
   * @param type
   * @return Invalide Number
   */
  public static byte[] getInvalideNumber(short type) {
    byte[] retour = null;

    switch (type) {

    case BOOLEAN:
      retour = new byte[] { (byte) 0xff };
      break;

    case UNSIGNED_INTEGER_8:
      retour = new byte[] { (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_16:
      retour = new byte[] { (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_24:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_32:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_40:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_48:
      retour = new byte[] { (byte) 0xff, (byte) 0xff , (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_56:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff , (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UNSIGNED_INTEGER_64:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff , (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;

    case SIGNED_INTEGER_8:
      retour = new byte[] { (byte) 0x80 };
      break;
    case SIGNED_INTEGER_16:
      retour = new byte[] { (byte) 0x80, 0 };
      break;
    case SIGNED_INTEGER_24:
      retour = new byte[] { (byte) 0x80, 0, 0 };
      break;
    case SIGNED_INTEGER_32:
      retour = new byte[] { (byte) 0x80, 0, 0, 0 };
      break;
    case SIGNED_INTEGER_40:
      retour = new byte[] { (byte) 0x80, 0, 0, 0 ,0 };
      break;
    case SIGNED_INTEGER_48:
      retour = new byte[] { (byte) 0x80, 0, 0, 0, 0 ,0 };
      break;
    case SIGNED_INTEGER_56:
      retour = new byte[] { (byte) 0x80, 0, 0, 0, 0, 0 ,0 };
      break;
    case SIGNED_INTEGER_64:
      retour = new byte[] { (byte) 0x80, 0, 0, 0, 0, 0, 0 ,0 };
      break
     

    case ENUMERATION_8:
      retour = new byte[] { (byte) 0xff };
      break;
    case ENUMERATION_16:
      retour = new byte[] { (byte) 0xff, (byte) 0xff };
      break;

    case TIME_OF_DAY:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case DATE:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case UTC_TIME:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;     
    case CLUSTER_ID:
      retour = new byte[] { (byte) 0xff, (byte) 0xff };
      break;
    case ATTRIBUTE_ID:
      retour = new byte[] { (byte) 0xff, (byte) 0xff };
      break;
    case BACNET_OID:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    case IEEE_ADDRESS:
      retour = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
      break;
    default:
      retour = new byte[0];
    }

    return retour;
  }

  /**
   *
   * V�rifie de type de l'objet en fonction du type de l'Attribut Renvoie la
   * taille des donnees en nombre de bits selon le type et 0 si elle ne peut
   * etre determinee
   *
   * @param type
   * @param object
   * @return True si ok
   */
  public static boolean checkInstanceObject(short type, Object object) {
    boolean retour = false;

    switch (type) {

    case BITMAP_8:
    case BITMAP_16:
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:
    case BITMAP_48:
    case BITMAP_56:
    case BITMAP_64:

      if (object instanceof BitSet)
        retour = true;
      break;
   

    case OCTET_STRING:
    case CHARACTER_STRING:
    case LONG_OCTET_STRING:
    case LONG_CHARACTER_STRING:     
      if (object instanceof String)
        retour = true;
      break;
    case BOOLEAN:
      if (object instanceof Boolean)
        retour = true;
      break;
    case GENERAL_DATA_8:
    case GENERAL_DATA_16:
    case GENERAL_DATA_24:
    case GENERAL_DATA_32:
    case GENERAL_DATA_40:
    case GENERAL_DATA_48:
    case GENERAL_DATA_56:
    case GENERAL_DATA_64:
    case UNSIGNED_INTEGER_8:
    case UNSIGNED_INTEGER_16:
    case UNSIGNED_INTEGER_24:
    case UNSIGNED_INTEGER_32:
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:
    case UNSIGNED_INTEGER_64:
    case SIGNED_INTEGER_8:
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:
    case SIGNED_INTEGER_56:
    case SIGNED_INTEGER_64:
    case ENUMERATION_8:
    case ENUMERATION_16:
    case UTC_TIME:
    case CLUSTER_ID:
    case ATTRIBUTE_ID:
    case BACNET_OID:
    case IEEE_ADDRESS:
      if (object instanceof Long)
        retour = true;
      break;
    case TIME_OF_DAY:
    case DATE:
      if (object instanceof Date)
        retour = true;
      break;

    case FLOATING_SEMI:
    case FLOATING_SINGLE:
      if (object instanceof Float)
        retour = true;
      break;
    case FLOATING_DOUBLE:
      if (object instanceof Double)
        retour = true;
      break;
    }

    return retour;
  }

  public static Class getJavaType(short type) {
    Class retour = null;

    switch (type) {

    case BITMAP_8:
    case BITMAP_16:
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:
    case BITMAP_48:
    case BITMAP_56:
    case BITMAP_64:     
      retour = BitSet.class;
      break;   
    case OCTET_STRING:
    case CHARACTER_STRING:
    case LONG_OCTET_STRING:
    case LONG_CHARACTER_STRING:     
      retour = String.class;
      break;
    case BOOLEAN:
      retour = Boolean.class;
      break;
    case GENERAL_DATA_8:
    case GENERAL_DATA_16:
    case GENERAL_DATA_24:
    case GENERAL_DATA_32:
    case GENERAL_DATA_40:
    case GENERAL_DATA_48:
    case GENERAL_DATA_56:
    case GENERAL_DATA_64:
    case UNSIGNED_INTEGER_8:
    case UNSIGNED_INTEGER_16:
    case UNSIGNED_INTEGER_24:
    case UNSIGNED_INTEGER_32:
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:
    case UNSIGNED_INTEGER_64:
    case SIGNED_INTEGER_8:
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:
    case SIGNED_INTEGER_56:
    case SIGNED_INTEGER_64:
    case ENUMERATION_8:
    case ENUMERATION_16:
    case UTC_TIME:
    case CLUSTER_ID:
    case ATTRIBUTE_ID:
    case BACNET_OID:
    case IEEE_ADDRESS:
      retour = Long.class;
      break;
    case TIME_OF_DAY:
    case DATE:
      retour = Date.class;     
      break;
    case FLOATING_SEMI:
    case FLOATING_SINGLE:
      retour = Float.class;
      break;
    case FLOATING_DOUBLE:
      retour = Double.class;       
      break;
    }

    return retour;
  }

 
 
  /**
   * Renvoie la taille des donn�es en nombre de bits selon le type et 0 si
   * elle ne peut �tre d�termin�e
   *
   * @param type
   * @return taille en octet
   */
  public static short getNombreBits(short type) throws IllegalArgumentException {
    return (short) (((int) getBytesLength(type)) * 8);
  }

  public static BitSet setBitset(String data, int base) {
    if (base == 16) {
      String binary = "";
      String octetBinaire = "";
      for (int i = 0; i < data.length() / 2; i++) {
        binary = binary + "00000000";
        octetBinaire = Integer.toBinaryString(Integer.valueOf(data.substring(i * 2, i * 2 + 2), base).intValue());
        binary = binary.substring(0, binary.length() - octetBinaire.length()) + octetBinaire;
      }
      data = binary;
    }
    StringBuffer buffer = new StringBuffer(data);
    // on defini un BitSet de meme longueur que le StringBuffer
    BitSet bitset = new BitSet(buffer.length());
    int j = buffer.length() - 1;
    for (int i = 0; i < buffer.length(); i++) {
      char current = buffer.charAt(i);
      if (current == '0') {
        bitset.set(j--, false);
      } else {
        bitset.set(j--, true);
      }
    }
    return bitset;
  }

  public static Object decode(short type, String data, int base, boolean inverser) throws NumberFormatException, IllegalArgumentException {

    Object retour = null;
    int nbCaractParOctet = 0;

    String LIBELLE_EXCEPTION = "Taille de la chaine non conforme";

    /* Base 2 ou 16 */
    if (base == 16)
      nbCaractParOctet = 2;
    else if (base == 2)
      nbCaractParOctet = 8;
    else
      throw new NumberFormatException("Base non supportee");

    if (data == null) {
      throw new NumberFormatException("Donnees null");
    }

    if (inverser) {
      if (type != CHARACTER_STRING && type != OCTET_STRING && data.length() > nbCaractParOctet) {
        data = reverse(data, base);
      }
    }

    switch (type) {
    case GENERAL_DATA_8:
    case GENERAL_DATA_16:
    case GENERAL_DATA_24:
    case GENERAL_DATA_32:
    case GENERAL_DATA_40:
    case GENERAL_DATA_48:
    case GENERAL_DATA_56:
    case GENERAL_DATA_64:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = data;
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;

    case BOOLEAN:
      if (data.length() != 1 * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        short value = Short.valueOf(data.substring(0, 1 * nbCaractParOctet), base).shortValue();
        if (value == 0) {
          retour = new Boolean(false);
        } else if (value == 0xff) {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        } else {
          retour = new Boolean(true);
        }
      }
      break;

    case BITMAP_8:     
    case BITMAP_16:     
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:     
    case BITMAP_48:     
    case BITMAP_56:
    case BITMAP_64:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = setBitset(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case UNSIGNED_INTEGER_8:
    case UNSIGNED_INTEGER_16:
    case UNSIGNED_INTEGER_24:
    case UNSIGNED_INTEGER_32:
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break
    case UNSIGNED_INTEGER_64:
     
      //TODO
      break


    case SIGNED_INTEGER_8:     
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:
    case SIGNED_INTEGER_56:
    case SIGNED_INTEGER_64:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          String binarydata = new String();
          if (base == 16) {
            binarydata = "0000000000000000000000000000000000000000000000000000000000000000";
            binarydata = binarydata.substring(0,DataType.getBytesLength(type)*8-1);
            String octetBinaire = Long.toBinaryString(Long.valueOf(data, 16).longValue());
            binarydata = binarydata.substring(0, binarydata.length() - octetBinaire.length()) + octetBinaire;
          } else {
            binarydata = data;
          }
          retour = (Long.parseLong(binarydata.substring(0, 1), 2) == 1) ? Long.valueOf("-" + binarydata.substring(1)) : Long.valueOf(binarydata.substring(1));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
     
    case ENUMERATION_8:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;

    case ENUMERATION_16:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;

    case FLOATING_SEMI:
      String floating = null;
      if (true)
        throw new NumberFormatException("Unsupported type");

      /*
       * if( data.length() != 2*nboctet ) { throw new
       * NumberFormatException(LIBELLE_EXCEPTION); }else{ String
       * binarydata = new String(); if( base == 16 ){ binarydata =
       * "0000000000000000"; String octetBinaire =
       * Long.toBinaryString(Long.valueOf(data,16).longValue());
       * binarydata=
       * binarydata.substring(0,binarydata.length()-octetBinaire.length())
       * + octetBinaire; } else{ binarydata = data; }
       *
       * floating = new StringBuffer(binarydata).reverse().toString();
       *
       * int bits = Long.valueOf(floating,2).intValue(); int s = ((bits >>
       * 15) == 0) ? 1 : -1; int e = ((bits >> 10) & 0x1f); int m = (e ==
       * 0) ? (bits & 0x3ff) << 1 : (bits & 0x3ff) | 0x400;
       *
       * if(e == 0x1f){ if(m==1024){ if(s == -1) retour = new
       * Float("-Infinity"); else retour = new Float("+Infinity"); } else{
       * retour = new Float("NaN"); } }else{ if(e == 0x00 && m == 00){
       * if(s == -1) retour = new Float("-0"); else retour = new
       * Float("+0"); } else{ retour = new
       * Float(s*m*java.lang.Math.pow(2,e-15)); } } }
       */
      break;
    case FLOATING_SINGLE:
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        String binarydata = new String();
        if (base == 16) {
          binarydata = "00000000000000000000000000000000";
          String octetBinaire = Long.toBinaryString(Long.valueOf(data, 16).longValue());
          binarydata = binarydata.substring(0, binarydata.length() - octetBinaire.length()) + octetBinaire;
        } else {
          binarydata = data;
        }

        floating = new StringBuffer(binarydata).reverse().toString();
        // System.out.println("floating  = " +floating );

        int bits = Long.valueOf(floating, 2).intValue();
        int s = ((bits >> 31) == 0) ? 1 : -1;
        int e = ((bits >> 23) & 0xff);
        int m = (e == 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;
        // System.out.println("s = " + s +" e = " +e +" m = " +m);

        retour = new Float(s * m * java.lang.Math.pow(2, e - 150));
        // System.out.println(retour );
      }
      break;
    case FLOATING_DOUBLE:
      if (true)
        throw new NumberFormatException("Unsupported type");
      /*
       * if( data.length() != 8*nboctet ) { throw new
       * NumberFormatException(LIBELLE_EXCEPTION); }else{ String
       * binarydata = new String(); if( base == 16 ){ binarydata =
       * "0000000000000000000000000000000000000000000000000000000000000000"
       * ; String octetBinaire =
       * Long.toBinaryString(Long.valueOf(data.substring
       * (1),16).longValue()); binarydata=
       * binarydata.substring(0,binarydata.length()-octetBinaire.length())
       * + octetBinaire; } else{ binarydata = data; }
       *
       * floating = new StringBuffer(binarydata).reverse().toString();
       * System.out.println("FLOATING_DOUBLE = "+floating + " " +
       * floating.length()); long bits =
       * Long.valueOf(floating.substring(1),2).longValue();;
       * System.out.println(bits); int s = 1; if(bits!=0){ if
       * (floating.substring(0,1).equals("1")){ bits = -1 * bits ; } s =
       * ((bits >> 63) == 0) ? 1 : -1; } else{ if
       * (floating.substring(0,1).equals("1")){ s = -1; } }
       * System.out.println(bits); System.out.println("                  "
       * + Long.toBinaryString(bits) + " " +
       * Long.toBinaryString(bits).length());
       *
       * System.out.println("s = "+s); int e = (int)((bits >> 52) &
       * 0x7ff); System.out.println("e = "); long m = (e == 0) ? (bits &
       * 0xfffffffffffffL) << 1 : (bits & 0xfffffffffffffL) |
       * 0x10000000000000L; System.out.println("m ="+m);
       *
       * if(e == 0x7ff){ if(m==0x10000000000000L){ if(s == -1) retour =
       * new Double("-Infinity"); else retour = new Double("+Infinity"); }
       * else{ retour = new Double("NaN"); } }else{ if(e == 0x000 && m ==
       * 0){ if(s == -1) retour = new Double("-0"); else retour = new
       * Double("+0"); } else{ retour = new
       * Double(s*m*java.lang.Math.pow(2,e-1075)); } } }
       */
      break;
    case OCTET_STRING:
      short taille = 0;
      if (true)
        throw new NumberFormatException("Unsupported type");
      break;
    case LONG_OCTET_STRING:
      taille = 0;
      if (true)
        throw new NumberFormatException("Unsupported type");
      break;
    case CHARACTER_STRING:
      taille = Short.valueOf(data.substring(0, 1 * nbCaractParOctet), base).shortValue();
      if ( taille == 0xff || base == 2 || data.length() < (1 * nbCaractParOctet) + (taille * nbCaractParOctet)) {
        throw new IllegalArgumentException("Taille de la chaine egale a 0xff ou base 2 ou l'argument taille ne coresponds pas a la taille de chaine finale");
      } else {
        retour = Element.HexToString(data.substring((1 * nbCaractParOctet), (1 * nbCaractParOctet) + (taille * nbCaractParOctet)));
      }
      break;
    case LONG_CHARACTER_STRING:
      taille = Short.valueOf(data.substring(0, 2 * nbCaractParOctet), base).shortValue();
      if ( taille == 0xffff || base == 2 || data.length() < (2 * nbCaractParOctet) + (taille * nbCaractParOctet)) {
        throw new IllegalArgumentException("Taille de la chaine egale a 0xffff ou base 2 ou l'argument taille ne coresponds pas a la taille de chaine finale");
      } else {
        retour = Element.HexToString(data.substring((2 * nbCaractParOctet), (2 * nbCaractParOctet) + (taille * nbCaractParOctet)));
      }
      break
     
    case TIME_OF_DAY:
      Calendar calendar = null;
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          calendar = new GregorianCalendar();

          short heure = Short.valueOf(data.substring(0, 1 * nbCaractParOctet), base).shortValue();
          if (heure < 0 || heure > 23) {
            if (heure == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument heure doit etre compris en 0 et 24");
            }
          } else {
            calendar.set(Calendar.HOUR_OF_DAY, heure);
          }
          short minute = Short.valueOf(data.substring(1 * nbCaractParOctet, 1 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (minute < 0 || minute > 59) {
            if (minute == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument minute doit etre compris en 0 et 59");
            }
          } else {
            calendar.set(Calendar.MINUTE, minute);
          }

          short seconde = Short.valueOf(data.substring(2 * nbCaractParOctet, 2 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (seconde < 0 || seconde > 59) {
            if (seconde == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument seconde doit etre compris en 0 et 59");
            }
          } else {
            calendar.set(Calendar.SECOND, seconde);
          }

          short milliseconde = Short.valueOf(data.substring(3 * nbCaractParOctet, 3 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (milliseconde < 0 || milliseconde > 99) {
            if (milliseconde == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument millisecond doit etre compris en 0 et 99");
            }
          } else {
            calendar.set(Calendar.MILLISECOND, milliseconde * 100);
          }

          retour = calendar.getTime();
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case UTC_TIME :
      if (data.length() != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case DATE:
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          calendar = new GregorianCalendar();

          short annee = Short.valueOf(data.substring(0, 1 * nbCaractParOctet), base).shortValue();
          if (annee < 0 || annee > 254) {
            if (annee == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument annee doit etre compris en 0 et 254");
            }
          } else {
            calendar.set(Calendar.YEAR, 1900 + annee);
          }

          short mois = Short.valueOf(data.substring(1 * nbCaractParOctet, 1 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (mois < 1 || mois > 12) {
            if (mois == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument mois doit etre compris en 1 et 12");
            }
          } else {
            calendar.set(Calendar.MONTH, mois);
          }

          short jour = Short.valueOf(data.substring(2 * nbCaractParOctet, 2 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (jour < 1 || jour > 1231) {
            if (jour == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument jour doit etre compris en 1 et 31");
            }
          } else {
            calendar.set(Calendar.DAY_OF_MONTH, jour);
          }

          short jourSemaine = Short.valueOf(data.substring(3 * nbCaractParOctet, 3 * nbCaractParOctet + 1 * nbCaractParOctet), base).shortValue();
          if (jourSemaine < 1 || jourSemaine > 7) {
            if (jourSemaine == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument jour semaine doit etre compris en 1 et 7");
            }
          } else {
            calendar.set(Calendar.DAY_OF_WEEK, jourSemaine);
          }

          retour = calendar.getTime();
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case CLUSTER_ID:
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
        if (((Long) retour).longValue() >= 0x8000 && ((Long) retour).longValue() <= 0xfbff) {
          throw new IllegalArgumentException("Cluster identifier reserved");
        }
      }
      break;
    case ATTRIBUTE_ID:
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
        if (((Long) retour).longValue() >= 0x4000 && ((Long) retour).longValue() <= 0xffff) {
          throw new IllegalArgumentException("Attribut identifier reserved");
        }
      }
      break;
    case BACNET_OID:
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case IEEE_ADDRESS:
      if (data.length() < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {

        if (data.compareToIgnoreCase(getInvalideNumber2String(type, base)) != 0) {
          short b1 = Short.parseShort(data.substring(0, 1), 16);
          if ((b1 & 0x8) == 0x8) {
            data = "-" + Integer.toHexString(b1 & 0x7) + data.substring(1);
          }
          retour = Long.valueOf(data, base);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    default:
      throw new NumberFormatException("Type invalide");

    }
    return retour;

  }

  /**
   * Renvoie un objet selon le type specifie TODO if base = 2, then x=0, so
   * y*(base/2)*(2*x) = always 0 ???
   *
   * @param type
   * @param data
   * @return Object
   */
  public static Object decode(short type, String data, int base) throws NumberFormatException, IllegalArgumentException {
    return decode(type, data, base, true);
  }

  public static Object decodeString(short type, String data, int base, boolean inverser) throws NumberFormatException, IllegalArgumentException {
    return decode(type, data, base, inverser);
  }

  public static Object decode(short type, byte[] data, boolean inverser) throws NumberFormatException, IllegalArgumentException {

    Object retour = null;
    int nbCaractParOctet = 1;

    String LIBELLE_EXCEPTION = "Taille de la chaine non conforme";

    if (data == null) {
      throw new NumberFormatException("Donnees null");
    }

    if (inverser) {
      if (type != CHARACTER_STRING && type != OCTET_STRING && data.length > nbCaractParOctet) {
        data = reverse(data);
      }

    }

    switch (type) {
    case GENERAL_DATA_8:     
    case GENERAL_DATA_16:     
    case GENERAL_DATA_24:     
    case GENERAL_DATA_32:     
    case GENERAL_DATA_40:
    case GENERAL_DATA_48:     
    case GENERAL_DATA_56:     
    case GENERAL_DATA_64:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = data;
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
 

    case BOOLEAN:
      if (data.length != 1 * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        short value = (short) (data[0] & 0xff);
        if (value == 0) {
          retour = new Boolean(false);
        } else if (value == 0xff) {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        } else {
          retour = new Boolean(true);
        }
      }
      break;

    case BITMAP_8:
    case BITMAP_16:
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:
    case BITMAP_48:
    case BITMAP_56:
    case BITMAP_64:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          BitSet bitset = new BitSet(getBytesLength(type) * 8);
          for (int j = 0; j < getBytesLength(type); j++) {
            for (int i = 0; i < 8; i++) {
              if ((data[j] >> i & 0x01) > 0)
                bitset.set(8 * j + i);
            }
          }
          retour = bitset;
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
 

    case UNSIGNED_INTEGER_8:     
    case UNSIGNED_INTEGER_16:     
    case UNSIGNED_INTEGER_24: 
    case UNSIGNED_INTEGER_32:     
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        long retourTmp = 0;
        if (!Arrays.equals(data, getInvalideNumber(type))) {               
          for(int i = 0 , j = DataType.getBytesLength(type)-1 ; i<DataType.getBytesLength(type);i ++) {
            long val = (long)(data[i] & 0xff )<< (8*j);
            retourTmp = (retourTmp + val);
            j--;
         
          retour = Long.valueOf(retourTmp);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case UNSIGNED_INTEGER_64:
      //TODO
      break
     

    case SIGNED_INTEGER_8:     
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:     
    case SIGNED_INTEGER_56:     
    case SIGNED_INTEGER_64:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          if ((data[0] & 0x80) > 0) {           
            long retourTmp = Long.valueOf( (data[0] & 0x7f)).longValue();           
            for(int i = 1; i<DataType.getBytesLength(type);i ++){
              retourTmp = retourTmp + Long.valueOf(data[i] << (8*i) & 0xff).longValue();
            }
            retour = Long.valueOf(retourTmp*-1);
          } else {
            long retourTmp = 0;           
            for(int i = 0; i<DataType.getBytesLength(type);i ++){
              retourTmp = retourTmp + Long.valueOf(data[i] << (8*i) & 0xff).longValue();
            }           
            retour = Long.valueOf(retourTmp);
          }
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
     

    case ENUMERATION_8:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf(data[0] & 0xff);
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;

    case ENUMERATION_16:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((data[0] & 0xff) << 8 | (data[1] & 0xff));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;

    case FLOATING_SEMI:
      String floating = null;
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        retour = new Float(java.lang.Math.pow(-1, (data[0] & 0x80)) * ((data[0] & 0x02) << 8 | data[1]) / 1024 * java.lang.Math.pow(2, (((data[0] & 0x7c) >> 2) & 0xff) - 15));
      }
      break;
    case FLOATING_SINGLE:
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        int e = (((data[0] & 0x7c) >> 2) & 0xff);
        int m = ((data[0] & 0x7F) << 16 | (data[1] & 0xff) << 8 | (data[2] & 0xff));

        retour = new Float(java.lang.Math.pow(-1, (data[0] & 0x80)) * m / 1024 * java.lang.Math.pow(2, e - 15));
      }
      break;
    case FLOATING_DOUBLE:
      if (true)
        throw new NumberFormatException("Unsupported type");
      else {
        int e = (((data[0] & 0x7c) >> 2) & 0xff);
        int m = (data[0] << 48 | data[1] << 40 | data[2] << 32 | data[3] << 24 | data[4] << 16 | data[5] << 8 | data[6]);

        retour = new Float(java.lang.Math.pow(-1, (data[0] & 0x80)) * m / 1024 * java.lang.Math.pow(2, e - 15));
      }
      break;
    case OCTET_STRING:
      short taille = 0;
      if (true)
        throw new NumberFormatException("Unsupported type");
      break;
    case LONG_OCTET_STRING:
      taille = 0;
      if (true)
        throw new NumberFormatException("Unsupported type");
      break
    case CHARACTER_STRING:
      taille = data[0];
      if ( taille == 0xff || data.length < (1 * nbCaractParOctet) + (taille * nbCaractParOctet)) {
        throw new IllegalArgumentException("Taille de la chaine egale a 0xff ou base 2 ou l'argument taille ne coresponds pas a la taille de chaine finale");
      } else {
        // TODO
        byte[] arrayTmp = new byte[taille];
        System.arraycopy(data, 1, arrayTmp, 0, taille);
        retour = new String(arrayTmp);
      }
      break;
    case LONG_CHARACTER_STRING:
      taille = (short)(data[1]*0xff + data[0]);
      if ( taille == 0xffff || data.length < (2 * nbCaractParOctet) + (taille * nbCaractParOctet)) {
        throw new IllegalArgumentException("Taille de la chaine egale a 0xffff ou base 2 ou l'argument taille ne coresponds pas a la taille de chaine finale");
      } else {
        // TODO
        byte[] arrayTmp = new byte[taille];
        System.arraycopy(data, 2, arrayTmp, 0, taille);
        retour = new String(arrayTmp);
      }
      break;
    case TIME_OF_DAY:
      Calendar calendar = null;
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          calendar = new GregorianCalendar();

          short heure = (short) (data[0] & 0xff);
          if (heure < 0 || heure > 23) {
            if (heure == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument heure doit etre compris en 0 et 24");
            }
          } else {
            calendar.set(Calendar.HOUR_OF_DAY, heure);
          }
          short minute = (short) (data[1] & 0xff);
          if (minute < 0 || minute > 59) {
            if (minute == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument minute doit etre compris en 0 et 59");
            }
          } else {
            calendar.set(Calendar.MINUTE, minute);
          }

          short seconde = (short) (data[2] & 0xff);
          if (seconde < 0 || seconde > 59) {
            if (seconde == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument seconde doit etre compris en 0 et 59");
            }
          } else {
            calendar.set(Calendar.SECOND, seconde);
          }

          short milliseconde = (short) (data[3] & 0xff);
          if (milliseconde < 0 || milliseconde > 99) {
            if (milliseconde == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument millisecond doit etre compris en 0 et 99");
            }
          } else {
            calendar.set(Calendar.MILLISECOND, milliseconde * 100);
          }

          retour = calendar.getTime();
        } else {
          throw new NumberFormatException(getInvalideNumber2String(TIME_OF_DAY, 16) + " est Invalide");
        }
      }
      break;
    case DATE:
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(TIME_OF_DAY))) {
          calendar = new GregorianCalendar();

          short annee = (short) (data[0] & 0xff);
          if (annee < 0 || annee > 254) {
            if (annee == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument annee doit etre compris en 0 et 254");
            }
          } else {
            calendar.set(Calendar.YEAR, 1900 + annee);
          }

          short mois = (short) (data[1] & 0xff);
          if (mois < 1 || mois > 12) {
            if (mois == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument mois doit etre compris en 1 et 12");
            }
          } else {
            calendar.set(Calendar.MONTH, mois);
          }

          short jour = (short) (data[2] & 0xff);
          if (jour < 1 || jour > 1231) {
            if (jour == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument jour doit etre compris en 1 et 31");
            }
          } else {
            calendar.set(Calendar.DAY_OF_MONTH, jour);
          }

          short jourSemaine = (short) (data[3] & 0xff);
          if (jourSemaine < 1 || jourSemaine > 7) {
            if (jourSemaine == 0xff) {
              // Unsed subfield
            } else {
              throw new IllegalArgumentException("L'argument jour semaine doit etre compris en 1 et 7");
            }
          } else {
            calendar.set(Calendar.DAY_OF_WEEK, jourSemaine);
          }

          retour = calendar.getTime();
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case UTC_TIME :
      if (data.length != DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((data[0] & 0xff) << 24 | (data[1] & 0xff) << 16 | (data[2] & 0xff) << 8 | (data[3] & 0xff));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
     
    case CLUSTER_ID:
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((data[0] & 0xff) << 8 | (data[1] & 0xff));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
        if (((Long) retour).longValue() >= 0x8000 && ((Long) retour).longValue() <= 0xfbff) {
          throw new IllegalArgumentException("Cluster identifier reserved");
        }
      }
      break;
    case ATTRIBUTE_ID:
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((data[0] & 0xff) << 8 | (data[1] & 0xff));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
        if (((Long) retour).longValue() >= 0x4000 && ((Long) retour).longValue() <= 0xffff) {
          throw new IllegalArgumentException("Attribut identifier reserved");
        }
      }
      break;
    case BACNET_OID:
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {
        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((data[0] & 0xff) << 24 | (data[1] & 0xff) << 16 | (data[2] & 0xff) << 8 | (data[3] & 0xff));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    case IEEE_ADDRESS:
      if (data.length < DataType.getBytesLength(type) * nbCaractParOctet) {
        throw new NumberFormatException(LIBELLE_EXCEPTION);
      } else {

        if (!Arrays.equals(data, getInvalideNumber(type))) {
          retour = Long.valueOf((long) (((data[0] & 0xff) << 56 | (data[1] & 0xff) << 48 | (data[2] & 0xff) << 40 | (data[3] & 0xff) << 32 | (data[4] & 0xff) << 24 | (data[5] & 0xff) << 16
              | (data[6] & 0xff) << 8 | (data[7] & 0xff))));
        } else {
          throw new NumberFormatException(getInvalideNumber2String(type, 16) + " est Invalide pour le type 0x" + Integer.toHexString(type));
        }
      }
      break;
    default:
      throw new NumberFormatException("Type invalide");

    }
    return retour;
  }

  public static String encode2String(short type, Object value, boolean inverse) throws IllegalArgumentException {

    String retour = null;

    switch (type) {
    case GENERAL_DATA_8:     
    case GENERAL_DATA_16:   
    case GENERAL_DATA_24:
    case GENERAL_DATA_32:
    case GENERAL_DATA_40:     
    case GENERAL_DATA_48:   
    case GENERAL_DATA_56:
    case GENERAL_DATA_64:     
      if (value != null) {
        if (value instanceof String) {
          if (((String) value).length() != DataType.getBytesLength(type))
            throw new IllegalArgumentException("Illegal Argument length");
          retour = Element.StringToHex((String) value, DataType.getBytesLength(type));
        } else
          throw new IllegalArgumentException("Instance is not String");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;

    case BOOLEAN:
      if (value != null) {
        if (value instanceof Boolean)
          retour = Element.BooleanToHex((Boolean) value, 1);
        else
          throw new IllegalArgumentException("Instance is not String");
      } else {
        retour = getInvalideNumber2String(BOOLEAN, 16);
      }
      break;

    case BITMAP_8:
    case BITMAP_16:
    case BITMAP_24:
    case BITMAP_32:
    case BITMAP_40:
    case BITMAP_48:
    case BITMAP_56:
    case BITMAP_64:     
      if (value != null) {
        if (value instanceof BitSet)
          retour = Element.BitSetToHex((BitSet) value, DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not BitSet");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;

    case UNSIGNED_INTEGER_8:
    case UNSIGNED_INTEGER_16:
    case UNSIGNED_INTEGER_24:     
    case UNSIGNED_INTEGER_32:
    case UNSIGNED_INTEGER_40:
    case UNSIGNED_INTEGER_48:
    case UNSIGNED_INTEGER_56:     
    case UNSIGNED_INTEGER_64:     
      if (value != null) {
        if (value instanceof Long)
          retour = Element.LongToHex((Long) value, DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;

    case SIGNED_INTEGER_8:
    case SIGNED_INTEGER_16:
    case SIGNED_INTEGER_24:
    case SIGNED_INTEGER_32:
    case SIGNED_INTEGER_40:
    case SIGNED_INTEGER_48:
    case SIGNED_INTEGER_56:
    case SIGNED_INTEGER_64:     
      if (value != null) {
        if (value instanceof Long)
          retour = Element.LongToHex((Long) value, DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }

      break;

    case ENUMERATION_8:
      if (value != null) {
        if (value instanceof Long)
          retour = Element.LongToHex((Long) value, DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case ENUMERATION_16:
      if (value != null) {

        if (value instanceof Long)
          retour = Element.LongToHex((Long) value, DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;

    case FLOATING_SEMI:
      if (value != null) {
        if (value instanceof Float) {
          String binarydata = new String();
          binarydata = "0000000000000000";
          String octetBinaire = Integer.toBinaryString(Float.floatToRawIntBits(((Float) value).floatValue()));
          binarydata = binarydata.substring(0, binarydata.length() - octetBinaire.length()) + octetBinaire;
          retour = Element.LongToHex(Long.valueOf(new StringBuffer(binarydata).reverse().toString(), 2), 4);
        } else
          throw new IllegalArgumentException("Instance is not Flaot");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case FLOATING_SINGLE:
      if (value != null) {
        if (value instanceof Float) {
          String binarydata = new String();
          binarydata = "00000000000000000000000000000000";
          String octetBinaire = Integer.toBinaryString(Float.floatToRawIntBits(((Float) value).floatValue()));
          binarydata = binarydata.substring(0, binarydata.length() - octetBinaire.length()) + octetBinaire;
          retour = Element.LongToHex(Long.valueOf(new StringBuffer(binarydata).reverse().toString(), 2), 4);
        } else
          throw new IllegalArgumentException("Instance is not Float");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case FLOATING_DOUBLE:
      if (value != null) {
        if (value instanceof Double) {
          String binarydata = new String();
          binarydata = "0000000000000000000000000000000000000000000000000000000000000000";
          String octetBinaire = Long.toBinaryString(Double.doubleToRawLongBits(((Double) value).doubleValue()));
          binarydata = binarydata.substring(0, binarydata.length() - octetBinaire.length()) + octetBinaire;
          retour = Element.LongToHex(Long.valueOf(new StringBuffer(binarydata).reverse().toString(), 2), 8);
        } else
          throw new IllegalArgumentException("Instance is not Double");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;

    case OCTET_STRING:
      if (value == null)
        value = "";
      if (true)
        throw new IllegalArgumentException("Unsupported");
      break;
    case CHARACTER_STRING:
      if (value == null)
        value = "";

      if (value instanceof String)
        retour = Element.IntegerToHex(new Integer(((String) value).length()), 1) + Element.StringToHex((String) value, ((String) value).length());
      else
        throw new IllegalArgumentException("Instance is not String");
      break;

    case TIME_OF_DAY:
      if (value != null) {
        if (value instanceof Date) {
          retour = Element.TimeToHex((Date) value);
        } else
          throw new IllegalArgumentException("Instance is not Date");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case DATE:
      if (value != null) {
        if (value instanceof Date) {
          retour = Element.DateToHex((Date) value);
        } else
          throw new IllegalArgumentException("Instance is not Date");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case CLUSTER_ID:
      if (value != null) {
        if (value instanceof Long && ((Long) value).longValue() >= 0x0000 && ((Long) value).longValue() <= 0xffff)
          retour = Element.LongToHex(((Long) value), DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long or invalide valeur");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }

      break;
    case ATTRIBUTE_ID:
      if (value != null) {
        if (value instanceof Long) {
          retour = Element.LongToHex(((Long) value), DataType.getBytesLength(type));
        } else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case BACNET_OID:
      if (value != null) {
        if (value instanceof Long)
          retour = Element.LongToHex(((Long) value), DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    case IEEE_ADDRESS:
      if (value != null) {
        if (value instanceof Long)
          // retour = Long.toHexString(((Long) value).longValue());
          retour = Element.LongToHex(((Long) value), DataType.getBytesLength(type));
        else
          throw new IllegalArgumentException("Instance is not Long");
      } else {
        retour = getInvalideNumber2String(type, 16);
      }
      break;
    }

    int nboctet = 2;
    if (inverse) {
      if (type != CHARACTER_STRING && type != OCTET_STRING && retour != null && retour.length() > nboctet) {
        retour = reverse(retour, 16);
      }
    }

    return retour;
  }

  /**
   * Renvoie la valeur hexadecimale de l'attribut
   *
   * @param type
   * @param data
   * @return String hexa
   */
  public static String encode2String(short type, Object value) throws IllegalArgumentException {

    String retour = null;

    retour = encode2String(type, value, RETOURNER);

    return retour;
  }

  public static byte[] encode(short type, Object value) throws IllegalArgumentException {

    return stringHex2ByteArray(encode2String(type, value));
  }

  public static byte[] encode(short type, Object value, boolean inverse) throws IllegalArgumentException {

    return stringHex2ByteArray(encode2String(type, value, inverse));
  }

  private static String binaryToString(String binaryString) {
    byte bytes[] = new byte[(binaryString.length() / 8) / 2];
    byte octet = 0;
    int j = 0;
    for (int i = 0; i < binaryString.length(); i = i + 2) {
      try {
        // Seulement les caracteres imprimable solution Tini en8
        // remplacement
        // de l'expresion reguliere
        octet = Byte.parseByte(binaryString.substring(i, i + (8 * 2)), 2);
        if (octet > 33 && octet < 249) { // entre 33 et 249 au pif
          bytes[j++] = octet;
        } else {
          bytes[j++] = " ".getBytes()[1];
        }
      } catch (NumberFormatException e) {
        // bytes[j++] = Byte.parseByte("00",16);
      }
    }
    // Supprime tous les caracteres nom imprimable avec
    // return new String(bytes).replaceAll("[^\\p{Print}]","");
    // mais ne marche pas sur Tini voir au dessus

    return new String(bytes).substring(0, j);
  }

  public static String reverse(String data, int base) {
    int nboctet = 0;

    if (RETOURNER) {
      if (base == 16)
        nboctet = 2;
      else if (base == 2)
        nboctet = 8;
      else
        throw new NumberFormatException("Base non supportee");

      if ((data.length() % 2) != 0) {
        throw new NumberFormatException("Bad data size (odd length)");
      }

      StringBuffer reverse = new StringBuffer();
      for (int i = data.length(); i >= nboctet - 1; i = i - nboctet) {
        reverse.append(data.substring(i - nboctet, i));
      }
      if (reverse.length() > 0)
        data = reverse.toString();
    }
    return data;
  }

  public static byte[] reverse(byte[] data) {

    byte[] retour = new byte[data.length];

    if (RETOURNER) {
      int j = 0;
      for (int i = data.length - 1; i >= 0; i--) {
        retour[j++] = data[i];
      }
    }

    return retour;
  }

  public static byte intToByte(int value) {

    byte result;

    value = value & 0xff;

    if ((value & 0x80) != 0) {
      result = (byte) (Byte.parseByte(Integer.toHexString(value & 0x7f), 16) - 128);
    } else {
      result = Byte.parseByte(Integer.toHexString(value), 16);
    }

    return result;
  }

  public static byte[] stringHex2ByteArray(String data) {

    byte[] retour = new byte[data.length() / 2];

    int j = 0;
    for (int i = 0; i < data.length(); i = i + 2) {
      retour[j++] = (byte) (Integer.parseInt(data.substring(i, i + 2), 16) & 0xff);
    }
    return retour;
  }

  /**
   * Retourne le contenu d'untableau de byte en chaine de caractère avec les
   * chiffre hexadécimaux
   *
   * @param tabByte
   *            tableau de byte
   * @isZgdNotifyreturn chaîne de caractère.
   */
  public static String tabByteToString(byte[] tabByte) {
    StringBuffer valRetour = null;
    if (tabByte != null) {
      valRetour = new StringBuffer();
      for (int i = 0; i < tabByte.length; i++) {
        valRetour.append(byteToHexString(tabByte[i]));
      }
    }

    if (valRetour == null) {
      return null;
    }
    return valRetour.toString().toUpperCase();
  }

  /**
   * Transforme un byte en valeur hexadécimale
   *
   * @param data
   *            le byte
   * @return un String de deux caractère
   */
  public static String byteToHexString(byte data) {
    String valRetour = "";
    int valeur = data & 0xFF;
    if (valeur <= 0xF) {
      valRetour += "0";
    }
    valRetour += Integer.toHexString(valeur).toUpperCase();
    return valRetour;
  }

  public static byte inversionByte(byte l_value_in) {
    byte l_value_out = 0;

    for (int i = 0; i < 8; i++, l_value_out = (byte) (((l_value_in >> i) & 0x01) == 0 ? l_value_out : l_value_out | (0x80 >> i)))
      ;

    return l_value_out;
  }
 
  public static byte inversionQuartet(byte l_value_in) {
   
    return (byte)((l_value_in<<4)&0xf0 | (l_value_in>>>4));
   
  }

 
 
  /**
     * ZigBee_base_driver_RFC_pollution
     * Commentaire Fabrice Blache :
     * Le code ci dessous est là pour assurer la compatible avec la spécification DSS mais les noms d'interfaces ne sont pas compatibles avec mon utilisation de ZCL en tant que modèle d'abstraction. C'est une polution de ma modélisation.
     * The code below is to ensure compatible with the DSS specification but the interface names are not compatible with my use of ZCL as abstraction model. This is a polution of my modeling.
     */
   
  /**
   * get data type in String form
   * @param type
   * @return type name
   * @throws IllegalArgumentException if unknown type
   */
   public static ZigBeeDataTypeDescription getZigBeeDataTypeDescription(short type) throws IllegalArgumentException {
     ZigBeeDataTypeDescription retour = null;
          
      switch (type & 0xff) {
      case GENERAL_DATA_8:
        retour = ZigBeeGeneralData8.getInstance();
        break;
      case GENERAL_DATA_16:
        retour = ZigBeeGeneralData16.getInstance();
        break;
      case GENERAL_DATA_24:
        retour = ZigBeeGeneralData24.getInstance();
        break;
      case GENERAL_DATA_32:
        retour = ZigBeeGeneralData32.getInstance();
        break;
      case GENERAL_DATA_40:
        retour = ZigBeeGeneralData40.getInstance();
        break;
      case GENERAL_DATA_48:
        retour = ZigBeeGeneralData48.getInstance();
        break;
      case GENERAL_DATA_56:
        retour = ZigBeeGeneralData56.getInstance();
        break;
      case GENERAL_DATA_64:
        retour = ZigBeeGeneralData64.getInstance();
        break;
      case BOOLEAN:
        retour = ZigBeeBoolean.getInstance();
        break;
      case BITMAP_8:
        retour = ZigBeeBitmap8.getInstance();
        break;
      case BITMAP_16:
        retour = ZigBeeBitmap16.getInstance();
        break;
      case BITMAP_24:
        retour = ZigBeeBitmap24.getInstance();
        break;
      case BITMAP_32:
        retour = ZigBeeBitmap32.getInstance();
        break;
      case BITMAP_40:
        retour = ZigBeeBitmap40.getInstance();
        break;
      case BITMAP_48:
        retour = ZigBeeBitmap48.getInstance();
        break;
      case BITMAP_56:
        retour = ZigBeeBitmap56.getInstance();
        break;
      case BITMAP_64:
        retour = ZigBeeBitmap64.getInstance();
        break;
      case UNSIGNED_INTEGER_8:
        retour = ZigBeeUnsignedInteger8.getInstance();
        break;
      case UNSIGNED_INTEGER_16:
        retour = ZigBeeUnsignedInteger16.getInstance();
        break;
      case UNSIGNED_INTEGER_24:
        retour = ZigBeeUnsignedInteger24.getInstance();
        break;
      case UNSIGNED_INTEGER_32:
        retour = ZigBeeUnsignedInteger32.getInstance();
        break;
      case UNSIGNED_INTEGER_40:
        retour = ZigBeeUnsignedInteger40.getInstance();
        break;
      case UNSIGNED_INTEGER_48:
        retour = ZigBeeUnsignedInteger48.getInstance();
        break;
      case UNSIGNED_INTEGER_56:
        retour = ZigBeeUnsignedInteger56.getInstance();
        break;
      case UNSIGNED_INTEGER_64:    
        retour = ZigBeeUnsignedInteger64.getInstance();
        break;
      case SIGNED_INTEGER_8:
        retour = ZigBeeSignedInteger8.getInstance();
        break;
      case SIGNED_INTEGER_16:
        retour = ZigBeeSignedInteger16.getInstance();
        break;
      case SIGNED_INTEGER_24:
        retour = ZigBeeSignedInteger24.getInstance();
        break;
      case SIGNED_INTEGER_32:
        retour = ZigBeeSignedInteger32.getInstance();
        break;
      case SIGNED_INTEGER_40:
        retour = ZigBeeSignedInteger40.getInstance();
        break;
      case SIGNED_INTEGER_48:
        retour = ZigBeeSignedInteger48.getInstance();
        break;
      case SIGNED_INTEGER_56:
        retour = ZigBeeSignedInteger56.getInstance();
        break;
      case SIGNED_INTEGER_64:    
        retour = ZigBeeSignedInteger64.getInstance();
        break;
      case ENUMERATION_8:
        retour = ZigBeeEnumeration8.getInstance();
        break;
      case ENUMERATION_16:
        retour = ZigBeeEnumeration16.getInstance();
        break;
      case FLOATING_SEMI:
        retour = ZigBeeFloatingSemi.getInstance();
        break;
      case FLOATING_SINGLE:
        retour = ZigBeeFloatingSingle.getInstance();
        break;
      case FLOATING_DOUBLE:
        retour = ZigBeeFloatingDouble.getInstance();
        break;
      case OCTET_STRING:     
        retour = ZigBeeOctetString.getInstance();
        break;
      case CHARACTER_STRING:     
        retour = ZigBeeCharacterString.getInstance();
        break;
      case LONG_OCTET_STRING:        
        retour = ZigBeeLongOctetString.getInstance();
        break;
      case LONG_CHARACTER_STRING:    
        retour = ZigBeeLongCharacterString.getInstance();
        break;
      case ARRAY:    
        retour = ZigBeeArray.getInstance();
        break;
      case STRUCTURE:    
        retour = ZigBeeStructure.getInstance();
        break;
      case SET:    
        retour = ZigBeeSet.getInstance();
        break;
      case BAG:
        retour = ZigBeeBag.getInstance();
        break;
      case TIME_OF_DAY:
        retour = ZigBeeTimeOfDay.getInstance();
        break;
      case DATE:
        retour = ZigBeeDate.getInstance();
        break;
      case UTC_TIME:
        retour = ZigBeeUTCTime.getInstance();
        break;
      case CLUSTER_ID:
        retour = ZigBeeClusterID.getInstance();
        break;
      case ATTRIBUTE_ID:
        retour = ZigBeeAttributeID.getInstance();
        break;
      case BACNET_OID:
        retour = ZigBeeBacnetOID.getInstance();
        break;
      case IEEE_ADDRESS:
        retour = ZigBeeIEEEAddress.getInstance();
        break;
      default:
        throw new IllegalArgumentException();
      }
     
      return retour;
    }

      /**
     * Fin Pollution
     */


   
}

 
TOP

Related Classes of com.francetelecom.m2m.gateway.service.machine.zigbee.common.DataType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.