    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#getAPIPacketParameters()
    133         */
    134        @Override
    135        protected LinkedHashMap<String, String> getAPIPacketParameters() {
    136                LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
    137                if (rfData != null)
    138                        parameters.put("RF Data", HexUtils.prettyHexString(HexUtils.byteArrayToHexString(rfData)));
    139                return parameters;
    140        }
    141}