001/** 002 * Copyright 2017, Digi International Inc. 003 * 004 * This Source Code Form is subject to the terms of the Mozilla Public 005 * License, v. 2.0. If a copy of the MPL was not distributed with this 006 * file, you can obtain one at http://mozilla.org/MPL/2.0/. 007 * 008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 015 */ 016package com.digi.xbee.api.models; 017 018import java.util.regex.Pattern; 019 020import com.digi.xbee.api.utils.HexUtils; 021 022/** 023 * This class represents an IMEI address used by cellular devices. 024 * 025 * <p>This address is only applicable for:</p> 026 * <ul> 027 * <li>Cellular</li> 028 * </ul> 029 * 030 * @since 1.2.0 031 */ 032public class XBeeIMEIAddress { 033 034 // Constants 035 private static final String ERROR_IMEI_NULL = "IMEI address cannot be null."; 036 private static final String ERROR_IMEI_TOO_LONG = "IMEI address cannot be longer than 8 bytes."; 037 private static final String ERROR_IMEI_INVALID = "Invalid IMEI address."; 038 039 private static final int HASH_SEED = 23; 040 041 private static final String IMEI_PATTERN = "^\\d{0,15}$"; 042 043 // Variables 044 private byte[] address; 045 046 /** 047 * Class constructor. Instantiates a new object of type 048 * {@code XBeeIMEIAddress} with the given parameter. 049 * 050 * @param address The IMEI address as byte array. 051 * 052 * @throws IllegalArgumentException If {@code address.length > 8}. 053 * @throws NullPointerException If {@code address == null}. 054 * 055 * @see #XBeeIMEIAddress(String) 056 */ 057 public XBeeIMEIAddress(byte[] address) { 058 if (address == null) 059 throw new NullPointerException(ERROR_IMEI_NULL); 060 if (address.length > 8) 061 throw new IllegalArgumentException(ERROR_IMEI_TOO_LONG); 062 063 generateByteAddress(address); 064 } 065 066 /** 067 * Class constructor. Instantiates a new object of type 068 * {@code XBeeIMEIAddress} with the given parameters. 069 * 070 * @param address The IMEI address as string. 071 * 072 * @throws IllegalArgumentException If the given address doesn't match the 073 * IMEI address pattern. 074 * @throws NullPointerException If {@code address == null}. 075 * 076 * @see #XBeeIMEIAddress(byte[]) 077 */ 078 public XBeeIMEIAddress(String address) { 079 if (address == null) 080 throw new NullPointerException(ERROR_IMEI_NULL); 081 082 if (!Pattern.matches(IMEI_PATTERN, address)) 083 throw new IllegalArgumentException(ERROR_IMEI_INVALID); 084 085 byte[] byteAddress = HexUtils.hexStringToByteArray(address); 086 087 generateByteAddress(byteAddress); 088 } 089 090 /** 091 * Generates and saves the IMEI byte address based on the given byte array. 092 * 093 * @param byteAddress The byte array used to generate the final IMEI byte 094 * address. 095 */ 096 private void generateByteAddress(byte[] byteAddress) { 097 this.address = new byte[8]; 098 099 int diff = 8 - byteAddress.length; 100 for (int i = 0; i < diff; i++) 101 this.address[i] = 0; 102 for (int i = diff; i < 8; i++) 103 this.address[i] = byteAddress[i - diff]; 104 } 105 106 /** 107 * Retrieves the IMEI address value. 108 * 109 * @return IMEI address value. 110 */ 111 public String getValue() { 112 return HexUtils.byteArrayToHexString(address).substring(1); 113 } 114 115 /* 116 * (non-Javadoc) 117 * @see java.lang.Object#equals(java.lang.Object) 118 */ 119 @Override 120 public boolean equals(Object obj) { 121 if (obj == null) 122 return false; 123 if (!(obj instanceof XBeeIMEIAddress)) 124 return false; 125 XBeeIMEIAddress addr = (XBeeIMEIAddress)obj; 126 return addr.getValue().equals(getValue()); 127 } 128 129 /* 130 * (non-Javadoc) 131 * @see java.lang.Object#hashCode() 132 */ 133 @Override 134 public int hashCode() { 135 int hash = HASH_SEED; 136 for (byte b:getValue().getBytes()) 137 hash = hash * (hash + b); 138 return hash; 139 } 140 141 /* 142 * (non-Javadoc) 143 * @see java.lang.Object#toString() 144 */ 145 @Override 146 public String toString() { 147 return getValue(); 148 } 149}