001/** 002 * Copyright (c) 2014 Digi International Inc., 003 * All rights not expressly granted are reserved. 004 * 005 * This Source Code Form is subject to the terms of the Mozilla Public 006 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 007 * You can obtain one at http://mozilla.org/MPL/2.0/. 008 * 009 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343 010 * ======================================================================= 011 */ 012package com.digi.xbee.api.packet; 013 014import java.io.ByteArrayOutputStream; 015import java.io.IOException; 016import java.util.Arrays; 017import java.util.LinkedHashMap; 018 019import org.slf4j.Logger; 020import org.slf4j.LoggerFactory; 021 022import com.digi.xbee.api.utils.HexUtils; 023 024/** 025 * This class represents a basic and unknown XBee packet where the payload is 026 * set as a byte array without a defined structure. 027 * 028 * @see XBeeAPIPacket 029 */ 030public class UnknownXBeePacket extends XBeeAPIPacket { 031 032 // Constants. 033 private static final int MIN_API_PAYLOAD_LENGTH = 1; // 1 (Frame type) 034 035 // Variables 036 protected byte[] rfData; 037 038 private Logger logger; 039 040 /** 041 * Creates a new {@code UnknownXBeePacket} from the given payload. 042 * 043 * @param payload The API frame payload. The first byte will be the frame 044 * type. 045 * The byte array must be in {@code OperatingMode.API} mode. 046 * 047 * @return Parsed Unknown packet. 048 * 049 * @throws IllegalArgumentException if {@code payload.length < }{@value #MIN_API_PAYLOAD_LENGTH}. 050 * @throws NullPointerException if {@code payload == null}. 051 */ 052 public static UnknownXBeePacket createPacket(byte[] payload) { 053 if (payload == null) 054 throw new NullPointerException("Unknown packet payload cannot be null."); 055 056 // 1 (Frame type) 057 if (payload.length < MIN_API_PAYLOAD_LENGTH) 058 throw new IllegalArgumentException("Incomplete Unknown packet."); 059 060 // payload[0] is the frame type. 061 int apiID = payload[0] & 0xFF; 062 int index = 1; 063 064 byte[] commandData = null; 065 if (index < payload.length) 066 commandData = Arrays.copyOfRange(payload, index, payload.length); 067 068 return new UnknownXBeePacket(apiID, commandData); 069 } 070 071 /** 072 * Class constructor. Instantiates an XBee packet with the given packet 073 * data. 074 * 075 * @param apiIDValue The XBee API integer value of the packet. 076 * @param rfData The XBee RF Data. 077 * 078 * @throws IllegalArgumentException if {@code apiIDValue < 0} or 079 * if {@code apiIDValue > 255}. 080 */ 081 public UnknownXBeePacket(int apiIDValue, byte[] rfData) { 082 super(apiIDValue); 083 this.rfData = rfData; 084 this.logger = LoggerFactory.getLogger(UnknownXBeePacket.class); 085 } 086 087 /* 088 * (non-Javadoc) 089 * @see com.digi.xbee.api.packet.XBeeAPIPacket#getAPIPacketSpecificData() 090 */ 091 @Override 092 protected byte[] getAPIPacketSpecificData() { 093 ByteArrayOutputStream data = new ByteArrayOutputStream(); 094 try { 095 if (rfData != null) 096 data.write(rfData); 097 } catch (IOException e) { 098 logger.error(e.getMessage(), e); 099 } 100 return data.toByteArray(); 101 } 102 103 /* 104 * (non-Javadoc) 105 * @see com.digi.xbee.api.packet.XBeeAPIPacket#needsAPIFrameID() 106 */ 107 @Override 108 public boolean needsAPIFrameID() { 109 return false; 110 } 111 112 /** 113 * Sets the XBee RF Data. 114 * 115 * @param rfData The new XBee RF Data. 116 */ 117 public void setRFData(byte[] rfData) { 118 this.rfData = rfData; 119 } 120 121 /** 122 * Returns the XBee RF Data of the packet. 123 * 124 * @return The RF Data. 125 */ 126 public byte[] getRFData() { 127 return rfData; 128 } 129 130 /* 131 * (non-Javadoc) 132 * @see com.digi.xbee.api.packet.XBeeAPIPacket#isBroadcast() 133 */ 134 @Override 135 public boolean isBroadcast() { 136 return false; 137 } 138 139 /* 140 * (non-Javadoc) 141 * @see com.digi.xbee.api.packet.XBeeAPIPacket#getAPIPacketParameters() 142 */ 143 @Override 144 protected LinkedHashMap<String, String> getAPIPacketParameters() { 145 LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>(); 146 if (rfData != null) 147 parameters.put("RF Data", HexUtils.prettyHexString(HexUtils.byteArrayToHexString(rfData))); 148 return parameters; 149 } 150}