/** * Class constructor. Instantiates a new * {@code RemoteATCommandResponsePacket} object with the given parameters. * * @param frameID frame ID. * @param sourceAddress64 64-bit address of the remote radio returning * response. * @param sourceAddress16 16-bit network address of the remote. * @param command The AT command. * @param status The command status. * @param commandValue The AT command response value. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255}. * @throws ArgumentNullException if {@code sourceAddress64 == null} or * if {@code sourceAddress16 == null} or * if {@code command == null} or * if {@code status == null}. * * @see com.digi.xbee.api.models.ATCommandStatus * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteATCommandResponsePacket(byte frameID, XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, String command, ATCommandStatus status, byte[] commandValue) : base(APIFrameType.REMOTE_AT_COMMAND_RESPONSE) { if (sourceAddress64 == null) { throw new ArgumentNullException("64-bit source address cannot be null."); } if (sourceAddress16 == null) { throw new ArgumentNullException("16-bit source address cannot be null."); } if (command == null) { throw new ArgumentNullException("AT command cannot be null."); } if (status == null) { throw new ArgumentNullException("AT command status cannot be null."); } if (frameID < 0 || frameID > 255) { throw new ArgumentException("Frame ID must be between 0 and 255."); } this.frameID = frameID; this.sourceAddress64 = sourceAddress64; this.sourceAddress16 = sourceAddress16; this.Command = command; this.Status = status; this.commandValue = commandValue; this.logger = LogManager.GetLogger <RemoteATCommandResponsePacket>(); }
/** * Retrieves the 16-bit address of the given remote device. * * @param device The remote device to get the 16-bit address. * * @return The 16-bit address of the device, {@code null} if it does not * contain a valid one. */ private XBee16BitAddress Get16BitAddress(RemoteXBeeDevice device) { if (device == null) { return(null); } XBee16BitAddress address = null; switch (device.XBeeProtocol) { case XBeeProtocol.RAW_802_15_4: address = ((RemoteRaw802Device)device).Get16BitAddress(); break; case XBeeProtocol.ZIGBEE: address = ((RemoteZigBeeDevice)device).Get16BitAddress(); break; default: // TODO should we allow this operation for general remote devices? address = device.Get16BitAddress(); break; } return(address); }
/** * Sends the provided data to the XBee device of the network corresponding * to the given 16-bit address. * * <p>This method blocks until a success or error response arrives or the * configured receive timeout expires.</p> * * <p>The received timeout is configured using the {@code setReceiveTimeout} * method and can be consulted with {@code getReceiveTimeout} method.</p> * * <p>For non-blocking operations use the method * {@link #sendData(XBee16BitAddress, byte[])}.</p> * * @param address The 16-bit address of the XBee that will receive the data. * @param data Byte array containing data to be sent. * * @throws InterfaceNotOpenException if the device is not open. * @throws ArgumentNullException if {@code address == null} or * if {@code data == null}. * @throws TimeoutException if there is a timeout sending the data. * @throws XBeeException if there is any other XBee related exception. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see XBeeDevice#getReceiveTimeout() * @see XBeeDevice#setReceiveTimeout(int) * @see #sendData(RemoteXBeeDevice, byte[]) * @see #sendData(XBee64BitAddress, byte[]) * @see #sendDataAsync(RemoteXBeeDevice, byte[]) * @see #sendDataAsync(XBee16BitAddress, byte[]) * @see #sendDataAsync(XBee64BitAddress, byte[]) */ public void SendData(XBee16BitAddress address, byte[] data) /*throws TimeoutException, XBeeException */ { // Verify the parameters are not null, if they are null, throw an exception. if (address == null) { throw new ArgumentNullException("Address cannot be null"); } if (data == null) { throw new ArgumentNullException("Data cannot be null"); } // Check connection. if (!connectionInterface.SerialPort.IsOpen) { throw new InterfaceNotOpenException(); } // Check if device is remote. if (IsRemote) { throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device."); } logger.InfoFormat(ToString() + "Sending data to {0} >> {1}.", address, HexUtils.PrettyHexString(data)); XBeePacket xbeePacket = new TX16Packet(GetNextFrameID(), address, (byte)XBeeTransmitOptions.NONE, data); SendAndCheckXBeePacket(xbeePacket, false); }
/** * Class constructor. Instantiates a new * {@code IODataSampleRxIndicatorPacket} object with the given parameters. * * @param sourceAddress64 64-bit address of the sender. * @param sourceAddress16 16-bit address of the sender. * @param receiveOptions Receive options. * @param rfData Received RF data. * * @throws ArgumentException if {@code receiveOptions < 0} or * if {@code receiveOptions > 255} or * if {@code rfData.Length < 5}. * @throws ArgumentNullException if {@code sourceAddress64 == null} or * if {@code sourceAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeReceiveOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData) : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR) { if (sourceAddress64 == null) { throw new ArgumentNullException("64-bit source address cannot be null."); } if (sourceAddress16 == null) { throw new ArgumentNullException("16-bit source address cannot be null."); } this.sourceAddress64 = sourceAddress64; this.sourceAddress16 = sourceAddress16; this.ReceiveOptions = receiveOptions; this.RFData = rfData; if (rfData != null) { IOSample = new IOSample(rfData); } else { IOSample = null; } this.logger = LogManager.GetLogger <IODataSampleRxIndicatorPacket>(); }
/** * Class constructor. Instantiates a new {@code RemoteATCommandRequest} * object with the given parameters. * * @param frameID Frame ID. * @param destAddress64 64-bit address of the destination device. * @param destAddress16 16-bit address of the destination device. * @param transmitOptions Bitfield of supported transmission options. * @param command AT command. * @param parameter AT command parameter. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code destAddress64 == null} or * if {@code destAddress16 == null} or * if {@code command == null}. * * @see com.digi.xbee.api.models.XBeeTransmitOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16, byte transmitOptions, string command, byte[] parameter) : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST) { if (destAddress64 == null) { throw new ArgumentNullException("64-bit destination address cannot be null."); } if (destAddress16 == null) { throw new ArgumentNullException("16-bit destination address cannot be null."); } if (command == null) { throw new ArgumentNullException("AT command cannot be null."); } this.frameID = frameID; this.destAddress64 = destAddress64; this.destAddress16 = destAddress16; this.transmitOptions = transmitOptions; this.Command = command; this.parameter = parameter; this.logger = LogManager.GetLogger <RemoteATCommandPacket>(); }
/** * Creates a new remote XBee device with the provided 64-bit address, * 16-bit address, node identifier and the XBee device that is using this * data reader as the connection interface for the remote device. * * The new XBee device will be a {@code RemoteDigiMeshDevice}, * a {@code RemoteDigiPointDevice}, a {@code RemoteRaw802Device} or a * {@code RemoteZigBeeDevice} depending on the protocol of the local XBee * device. If the protocol cannot be determined or is unknown a * {@code RemoteXBeeDevice} will be created instead. * * @param addr64 The 64-bit address of the new remote device. It cannot be * {@code null}. * @param addr16 The 16-bit address of the new remote device. It may be * {@code null}. * @param ni The node identifier of the new remote device. It may be * {@code null}. * * @return a new remote XBee device with the given parameters. */ private RemoteXBeeDevice createRemoteXBeeDevice(XBee64BitAddress addr64, XBee16BitAddress addr16, String ni) { RemoteXBeeDevice device = null; switch (xbeeDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: device = new RemoteZigBeeDevice(xbeeDevice, addr64, addr16, ni); break; case XBeeProtocol.DIGI_MESH: device = new RemoteDigiMeshDevice(xbeeDevice, addr64, ni); break; case XBeeProtocol.DIGI_POINT: device = new RemoteDigiPointDevice(xbeeDevice, addr64, ni); break; case XBeeProtocol.RAW_802_15_4: device = new RemoteRaw802Device(xbeeDevice, addr64, addr16, ni); break; default: device = new RemoteXBeeDevice(xbeeDevice, addr64, addr16, ni); break; } return(device); }
/// <summary> /// Creates a new <seealso cref="RemoteATCommandPacket"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to a Remote AT Command packet (<c>0x17</c>). The byte array must be in <see cref="OperatingMode.API"/> /// mode.</param> /// <returns>Parsed Remote AT Command packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue()</c> /// or if <c>payload.Length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static RemoteATCommandPacket CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("Remote AT Command packet payload cannot be null."); } // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (transmit options byte) + 2 (AT command) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete Remote AT Command packet."); } if ((payload[0] & 0xFF) != APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue()) { throw new ArgumentException("Payload is not a Remote AT Command packet."); } // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 8 bytes of 64-bit address. XBee64BitAddress destAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Options byte. byte transmitOptions = payload[index]; index = index + 1; // 2 bytes of AT command. byte[] commandByte = new byte[] { payload[index], payload[index + 1] }; string command = Encoding.UTF8.GetString(commandByte, 0, commandByte.Length); index = index + 2; // Get data. byte[] parameterData = null; if (index < payload.Length) { parameterData = new byte[payload.Length - index]; Array.Copy(payload, index, parameterData, 0, parameterData.Length); } return(new RemoteATCommandPacket(frameID, destAddress64, destAddress16, transmitOptions, command, parameterData)); }
/** * Removes the given remote XBee device from the network. * * <p>Notice that this operation does not remove the remote XBee device * from the actual XBee network; it just tells the network object that it * will no longer contain that device. However, next time a discovery is * performed, it could be added again automatically.</p> * * <p>This method will check for a device that matches the 64-bit address * of the provided one, if found, that device will be removed from the * corresponding list. In case the 64-bit address is not defined, it will * use the 16-bit address for DigiMesh and ZigBee devices.</p> * * @param remoteDevice The remote device to be removed from the network. * * @throws ArgumentNullException if {@code RemoteDevice == null}. * * @see #addRemoteDevice(RemoteXBeeDevice) * @see #clearDeviceList() * @see RemoteXBeeDevice */ public void removeRemoteDevice(RemoteXBeeDevice remoteDevice) { if (remoteDevice == null) { throw new ArgumentNullException("Remote device cannot be null."); } RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. XBee64BitAddress addr64 = remoteDevice.Get64BitAddress(); if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { if (remotesBy64BitAddr.TryRemove(addr64, out devInNetwork)) { return; } } // If not found, look in the 16-bit map. XBee16BitAddress addr16 = Get16BitAddress(remoteDevice); if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'getDeviceBy16BitAddress' method. // Look for the 16-bit address in the 64-bit map. ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(addr16)) { RemoteXBeeDevice r; remotesBy64BitAddr.TryRemove(d.Get64BitAddress(), out r); return; } } // If not found, look for the 16-bit address in the 16-bit map. // Remove the device. if (remotesBy16BitAddr.TryRemove(addr16, out devInNetwork)) { return; } } // If the device does not contain a valid address log an error. if ((addr64 == null || addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) && (addr16 == null || addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS))) { logger.ErrorFormat("{0}Remote device '{1}' cannot be removed: 64-bit and 16-bit addresses must be specified.", localDevice.ToString(), remoteDevice.ToString()); } }
/** * Class constructor. Instantiates a new {@code RemoteRaw802Device} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote 802.15.4 device. * @param addr64 The 64-bit address to identify this remote 802.15.4 device. * @param addr16 The 16-bit address to identify this remote 802.15.4 device. * It might be {@code null}. * @param id The node identifier of this remote 802.15.4 device. It might be * {@code null}. * * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or * if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4} * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, string id) : base(localXBeeDevice, addr64, addr16, id) { // Verify the local device has 802.15.4 protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4) throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + "."); }
/// <summary> /// Class constructor. Instantiates a new <see cref="TX16Packet"/> object with the /// given parameters. /// </summary> /// <param name="frameID">The Frame ID.</param> /// <param name="destAddress16">The 16-bit address of the destination device.</param> /// <param name="transmitOptions">The bitfield of supported transmission options.</param> /// <param name="rfData">The RF Data that is sent to the destination device.</param> /// <exception cref="ArgumentException">If <c><paramref name="frameID"/> <![CDATA[<]]> 0</c> /// or if <c><paramref name="frameID"/> <![CDATA[>]]> 255</c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeTransmitOptions"/> /// <seealso cref="XBee16BitAddress"/> public TX16Packet(byte frameID, XBee16BitAddress destAddress16, byte transmitOptions, byte[] rfData) : base(APIFrameType.TX_16) { FrameID = frameID; DestAddress16 = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null."); TransmitOptions = transmitOptions; RFData = rfData; logger = LogManager.GetLogger <TX16Packet>(); }
/// <summary> /// Creates a new <see cref="TransmitPacket"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to a Transmit packet (<c>0x10</c>). The byte array must be in <see cref="OperatingMode.API"/> /// mode.</param> /// <returns>Parsed Transmit packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.TRANSMIT_REQUEST.GetValue()</c> /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static TransmitPacket CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("Transmit packet payload cannot be null."); } // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (broadcast radious) + 1 (options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete Transmit packet."); } if ((payload[0] & 0xFF) != APIFrameType.TRANSMIT_REQUEST.GetValue()) { throw new ArgumentException("Payload is not a Transmit packet."); } // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 8 bytes of 64-bit address. XBee64BitAddress destAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Broadcast radious byte. byte broadcastRadius = payload[index]; index = index + 1; // Options byte. byte options = payload[index]; index = index + 1; // Get RF data. byte[] rfData = null; if (index < payload.Length) { rfData = new byte[payload.Length - index]; Array.Copy(payload, index, rfData, 0, rfData.Length); } return(new TransmitPacket(frameID, destAddress64, destAddress16, broadcastRadius, options, rfData)); }
/// <summary> /// Class constructor. Instantiates a new <see cref="ReceivePacket"/> object with the /// given parameters. /// </summary> /// <param name="sourceAddress64">The 64-bit address of the sender device.</param> /// <param name="sourceAddress16">The 16-bit address of the sender device.</param> /// <param name="receiveOptions">The bitField of receive options.</param> /// <param name="rfData">The received RF data.</param> /// <exception cref="ArgumentException">If <c><paramref name="receiveOptions"/> <![CDATA[<]]> 0</c> /// or if <c><paramref name="receiveOptions"/> <![CDATA[>]]> 255</c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="sourceAddress64"/> == null</c> /// or if <c><paramref name="sourceAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeReceiveOptions"/> /// <seealso cref="XBee16BitAddress"/> /// <seealso cref="XBee64BitAddress"/> public ReceivePacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData) : base(APIFrameType.RECEIVE_PACKET) { SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit source address cannot be null."); SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit source address cannot be null."); ReceiveOptions = receiveOptions; RFData = rfData; logger = LogManager.GetLogger <ReceivePacket>(); }
/** * Class constructor. Instantiates a new {@code RemoteRaw802Device} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote 802.15.4 device. * @param addr64 The 64-bit address to identify this remote 802.15.4 device. * @param addr16 The 16-bit address to identify this remote 802.15.4 device. * It might be {@code null}. * @param id The node identifier of this remote 802.15.4 device. It might be * {@code null}. * * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or * if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4} * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, string id) : base(localXBeeDevice, addr64, addr16, id) { // Verify the local device has 802.15.4 protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4) { throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + "."); } }
/** * Class constructor. Instantiates a new {@code RemoteZigBeeDevice} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote ZigBee device. * @param addr64 The 64-bit address to identify this remote ZigBee device. * @param addr16 The 16-bit address to identify this remote ZigBee device. * It might be {@code null}. * @param ni The node identifier of this remote ZigBee device. It might be * {@code null}. * * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or * if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.ZIGBEE}. * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteZigBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, string ni) : base(localXBeeDevice, addr64, addr16, ni) { // Verify the local device has ZigBee protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.ZIGBEE) { throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.ZIGBEE.GetDescription() + "."); } }
/** * Class constructor. Instantiates a new {@code RemoteRaw802Device} object * interface to be used. * * @param localXBeeDevice The local 802.15.4 device that will behave as * connection interface to communicate with this * remote 802.15.4 device. * @param addr16 The 16-bit address to identify this remote 802.15.4 * device. * * @throws ArgumentException if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4}. * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr16 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress */ public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee16BitAddress addr16) : base(localXBeeDevice, XBee64BitAddress.UNKNOWN_ADDRESS) { // Verify the local device has 802.15.4 protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4) { throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + "."); } this.xbee16BitAddress = addr16; }
/// <summary> /// Class constructor. Instantiates a new <see cref="TransmitStatusPacket"/> object with the /// given parameters. /// </summary> /// <param name="frameID">The frame ID.</param> /// <param name="destAddress16">The 16-bit network address the packet was delivered to.</param> /// <param name="transmitRetryCount">The number of application transmission retries that took place.</param> /// <param name="transmitStatus">The transmit status.</param> /// <param name="discoveryStatus">The discovery status.</param> /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeDiscoveryStatus"/> /// <seealso cref="XBeeTransmitStatus"/> /// <seealso cref="XBee16BitAddress"/> public TransmitStatusPacket(byte frameID, XBee16BitAddress destAddress16, byte transmitRetryCount, XBeeTransmitStatus transmitStatus, XBeeDiscoveryStatus discoveryStatus) : base(APIFrameType.TRANSMIT_STATUS) { FrameID = frameID; DestAddress16 = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null."); TransmitRetryCount = transmitRetryCount; TransmitStatus = transmitStatus; DiscoveryStatus = discoveryStatus; logger = LogManager.GetLogger <TransmitStatusPacket>(); }
/** * Class constructor. Instantiates a new {@code TX16Packet} object with * the given parameters. * * @param frameID Frame ID. * @param destAddress16 16-bit address of the destination device. * @param transmitOptions Bitfield of supported transmission options. * @param rfData RF Data that is sent to the destination device. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code destAddress == null}. * * @see com.digi.xbee.api.models.XBeeTransmitOptions * @see com.digi.xbee.api.models.XBee16BitAddress */ public TX16Packet(byte frameID, XBee16BitAddress destAddress16, byte transmitOptions, byte[] rfData) : base(APIFrameType.TX_16) { Contract.Requires <ArgumentNullException>(destAddress16 != null, "16-bit destination address cannot be null."); this.frameID = frameID; this.destAddress16 = destAddress16; this.TransmitOptions = transmitOptions; this.RFData = rfData; this.logger = LogManager.GetLogger <TX16Packet>(); }
/** * Class constructor. Instantiates a new {@code TX16Packet} object with * the given parameters. * * @param frameID Frame ID. * @param destAddress16 16-bit address of the destination device. * @param transmitOptions Bitfield of supported transmission options. * @param rfData RF Data that is sent to the destination device. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code destAddress == null}. * * @see com.digi.xbee.api.models.XBeeTransmitOptions * @see com.digi.xbee.api.models.XBee16BitAddress */ public TX16Packet(byte frameID, XBee16BitAddress destAddress16, byte transmitOptions, byte[] rfData) : base(APIFrameType.TX_16) { Contract.Requires<ArgumentNullException>(destAddress16 != null, "16-bit destination address cannot be null."); this.frameID = frameID; this.destAddress16 = destAddress16; this.TransmitOptions = transmitOptions; this.RFData = rfData; this.logger = LogManager.GetLogger<TX16Packet>(); }
/// <summary> /// Class constructor. Instantiates a new <see cref="TransmitPacket"/> object with the /// given parameters. /// </summary> /// <param name="frameID">The Frame ID.</param> /// <param name="destAddress64">The 64-bit address of the destination device.</param> /// <param name="destAddress16">The 16-bit address of the destination device.</param> /// <param name="broadcastRadius">The maximum number of hops a broadcast transmission can occur.</param> /// <param name="transmitOptions">The bitfield of supported transmission options.</param> /// <param name="rfData">The RF Data that is sent to the destination device.</param> /// <exception cref="ArgumentException">If <c><paramref name="frameID"/> <![CDATA[<]]> 0</c> /// or if <c><paramref name="frameID"/> <![CDATA[>]]> 255</c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c> /// or if <c><paramref name="destAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeTransmitOptions"/> /// <seealso cref="XBee16BitAddress"/> /// <seealso cref="XBee64BitAddress"/> public TransmitPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16, byte broadcastRadius, byte transmitOptions, byte[] rfData) : base(APIFrameType.TRANSMIT_REQUEST) { FrameID = frameID; DestAddress64 = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null."); DestAddress16 = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null."); BroadcastRadius = broadcastRadius; TransmitOptions = transmitOptions; RFData = rfData; logger = LogManager.GetLogger <TransmitPacket>(); }
/** * Class constructor. Instantiates a new {@code RX16Packet} object with * the given parameters. * * @param sourceAddress16 16-bit address of the sender. * @param rssi Received signal strength indicator. * @param receiveOptions Bitfield indicating the receive options. * @param rfData Received RF data. * * @throws ArgumentException if {@code rssi < 0} or * if {@code rssi > 100} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code sourceAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeReceiveOptions * @see com.digi.xbee.api.models.XBee16BitAddress */ public RX16Packet(XBee16BitAddress sourceAddress16, byte rssi, byte receiveOptions, byte[] rfData) : base(APIFrameType.RX_16) { Contract.Requires<ArgumentNullException>(sourceAddress16 != null, "16-bit source address cannot be null."); Contract.Requires<ArgumentException>(rssi >= 0 && rssi <= 100, "RSSI value must be between 0 and 100."); this.sourceAddress16 = sourceAddress16; this.RSSI = rssi; this.ReceiveOptions = receiveOptions; this.RFData = rfData; this.logger = LogManager.GetLogger<RX16Packet>(); }
/// <summary> /// Class constructor. Instantiates a new <see cref="RemoteATCommandPacket"/> object with the /// given parameters. /// </summary> /// <param name="frameID">The Frame ID.</param> /// <param name="destAddress64">The 64-bit address of the destination device.</param> /// <param name="destAddress16">The 16-bit address of the destination device.</param> /// <param name="transmitOptions">The bitfield of supported transmission options.</param> /// <param name="command">The AT command.</param> /// <param name="parameter">The AT command parameter.</param> /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c> /// or if <c><paramref name="destAddress16"/> == null</c> /// or if <c><paramref name="command"/> == null</c>.</exception> /// <seealso cref="XBeeTransmitOptions"/> /// <seealso cref="XBee16BitAddress"/> /// <seealso cref="XBee64BitAddress"/> public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16, byte transmitOptions, string command, byte[] parameter) : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST) { FrameID = frameID; DestAddress64 = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null."); DestAddress16 = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null."); TransmitOptions = transmitOptions; Command = command ?? throw new ArgumentNullException("AT command cannot be null."); Parameter = parameter; logger = LogManager.GetLogger <RemoteATCommandPacket>(); }
/** * Class constructor. Instantiates a new {@code RX16Packet} object with * the given parameters. * * @param sourceAddress16 16-bit address of the sender. * @param rssi Received signal strength indicator. * @param receiveOptions Bitfield indicating the receive options. * @param rfData Received RF data. * * @throws ArgumentException if {@code rssi < 0} or * if {@code rssi > 100} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code sourceAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeReceiveOptions * @see com.digi.xbee.api.models.XBee16BitAddress */ public RX16Packet(XBee16BitAddress sourceAddress16, byte rssi, byte receiveOptions, byte[] rfData) : base(APIFrameType.RX_16) { Contract.Requires <ArgumentNullException>(sourceAddress16 != null, "16-bit source address cannot be null."); Contract.Requires <ArgumentException>(rssi >= 0 && rssi <= 100, "RSSI value must be between 0 and 100."); this.sourceAddress16 = sourceAddress16; this.RSSI = rssi; this.ReceiveOptions = receiveOptions; this.RFData = rfData; this.logger = LogManager.GetLogger <RX16Packet>(); }
/** * Creates a new {@code ReceivePacket} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Receive packet ({@code 0x90}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed ZigBee Receive packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.RECEIVE_PACKET.getValue()} or * if {@code payload.Length < {@value #MIN_API_PAYLOAD_LENGTH}} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static ReceivePacket createPacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("Receive packet payload cannot be null."); } // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete Receive packet."); } if ((payload[0] & 0xFF) != APIFrameType.RECEIVE_PACKET.GetValue()) { throw new ArgumentException("Payload is not a Receive packet."); } // payload[0] is the frame type. int index = 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 2 bytes of 16-bit address. XBee64BitAddress sourceAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Receive options byte receiveOptions = payload[index]; index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); //data = Arrays.copyOfRange(payload, index, payload.Length); } return(new ReceivePacket(sourceAddress64, sourceAddress16, receiveOptions, data)); }
/** * Class constructor. Instantiates a new {@code ReceivePacket} object * with the given parameters. * * @param sourceAddress64 64-bit address of the sender. * @param sourceAddress16 16-bit address of the sender. * @param receiveOptions Bitfield indicating the receive options. * @param rfData Received RF data. * * @throws ArgumentException if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code sourceAddress64 == null} or * if {@code sourceAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeReceiveOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public ReceivePacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData) : base(APIFrameType.RECEIVE_PACKET) { if (sourceAddress64 == null) throw new ArgumentNullException("64-bit source address cannot be null."); if (sourceAddress16 == null) throw new ArgumentNullException("16-bit source address cannot be null."); this.sourceAddress64 = sourceAddress64; this.sourceAddress16 = sourceAddress16; this.ReceiveOptions = receiveOptions; this.RFData = rfData; this.logger = LogManager.GetLogger<ReceivePacket>(); }
/// <summary> /// Class constructor. Instantiates a new <see cref="RX16Packet"/> object with the given parameters. /// </summary> /// <param name="sourceAddress16">The 16-bit address of the sender device.</param> /// <param name="rssi">The received signal strength indicator.</param> /// <param name="receiveOptions">The bitField of receive options.</param> /// <param name="rfData">The received RF data.</param> /// <exception cref="ArgumentOutOfRangeException">If <c><paramref name="rssi"/> <![CDATA[<]]> 0</c> /// or if <c><paramref name="rssi"/> <![CDATA[>]]> 255</c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="sourceAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeReceiveOptions"/> /// <seealso cref="XBee16BitAddress"/> public RX16Packet(XBee16BitAddress sourceAddress16, byte rssi, byte receiveOptions, byte[] rfData) : base(APIFrameType.RX_16) { if (rssi < 0 || rssi > 255) { throw new ArgumentOutOfRangeException("RSSI value must be between 0 and 255."); } SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit source address cannot be null."); RSSI = rssi; ReceiveOptions = receiveOptions; RFData = rfData; logger = LogManager.GetLogger <RX16Packet>(); }
/** * Returns the remote device already contained in the network whose 16-bit * address matches the given one. * * <p>Note that this method <b>does not perform a discovery</b>, only * returns the device that has been previously discovered.</p> * * @param address The 16-bit address of the device to be retrieved. * * @return The remote device in the network or {@code null} if it is not * found. * * @throws ArgumentException if {@code address.equals(XBee16BitAddress.UNKNOWN_ADDRESS)}. * @throws ArgumentNullException if {@code address == null}. * @throws OperationNotSupportedException if the protocol of the local XBee device is DigiMesh or Point-to-Multipoint. */ public RemoteXBeeDevice GetDevice(XBee16BitAddress address) /*throws OperationNotSupportedException */ { if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_MESH) { throw new OperationNotSupportedException("DigiMesh protocol does not support 16-bit addressing."); } if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_POINT) { throw new OperationNotSupportedException("Point-to-Multipoint protocol does not support 16-bit addressing."); } if (address == null) { throw new ArgumentNullException("16-bit address cannot be null."); } if (address.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { throw new ArgumentNullException("16-bit address cannot be unknown."); } logger.DebugFormat("{0}Getting device '{1}' from network.", localDevice.ToString(), address); // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'addRemoteDevice' method. RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(address)) { devInNetwork = d; break; } } // Look in the 16-bit map. if (devInNetwork == null) { devInNetwork = remotesBy16BitAddr[address]; } return(devInNetwork); }
/// <summary> /// Creates a new <see cref="TransmitStatusPacket"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to a Transmit Status packet (<c>0x8B</c>). The byte array must be in <see cref="OperatingMode.API"/> /// mode.</param> /// <returns>Parsed Transmit Status packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.TRANSMIT_STATUS.GetValue()</c> /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static TransmitStatusPacket CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("Transmit Status packet payload cannot be null."); } // 1 (Frame type) + 1 (frame ID) + 2 (16-bit address) + 1 (retry count) + 1 (delivery status) + 1 (discovery status) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete Transmit Status packet."); } if ((payload[0] & 0xFF) != APIFrameType.TRANSMIT_STATUS.GetValue()) { throw new ArgumentException("Payload is not a Transmit Status packet."); } // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; // 2 bytes of 16-bit address. XBee16BitAddress address = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Retry count byte. byte retryCount = payload[index]; index = index + 1; // Delivery status byte. byte deliveryStatus = payload[index]; index = index + 1; // Discovery status byte. byte discoveryStatus = payload[index]; // TODO if XBeeTransmitStatus is unknown???? return(new TransmitStatusPacket(frameID, address, retryCount, XBeeTransmitStatus.SUCCESS.Get(deliveryStatus), XBeeDiscoveryStatus.DISCOVERY_STATUS_ADDRESS_AND_ROUTE.Get(discoveryStatus))); }
/// <summary> /// Returns the 64bit and 16bit addresses of a packet. /// </summary> /// <remarks> /// Note this has different functionality than python, as it can accept any of 7 packets. /// The original python API only accepts 4 kinds. /// It is also somewhat redundant to Devices.XBeeNetwork.GetDataForRemote, although that takes a raw byte array instead of a packet /// </remarks> /// <param name="packet">The API packet to scrape addresses from</param> /// <returns>A pair of 64bit and 16bit addresses</returns> protected static Tuple <XBee64BitAddress, XBee16BitAddress> GetRemoteDeviceDataFromPacket(XBeeAPIPacket packet) { XBee64BitAddress x64bitAddr = null; XBee16BitAddress x16bitAddr = null; if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X64BIT_ADDR)) { x64bitAddr = (XBee64BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X64BIT_ADDR]; } if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X16BIT_ADDR)) { x16bitAddr = (XBee16BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X16BIT_ADDR]; } return(new Tuple <XBee64BitAddress, XBee16BitAddress>(x64bitAddr, x16bitAddr)); }
/// <summary> /// Creates a new <seealso cref="IODataSampleRxIndicatorPacket"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to an IO Data Sample RX Indicator packet (<c>0x92</c>). The byte array must be in /// <see cref="OperatingMode.API"/> mode.</param> /// <returns>Parsed IO Data Sample RX Indicator packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue()</c> /// or if <c>payload.Length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static IODataSampleRxIndicatorPacket CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("IO Data Sample RX Indicator packet payload cannot be null."); } // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete IO Data Sample RX Indicator packet."); } if ((payload[0] & 0xFF) != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue()) { throw new ArgumentException("Payload is not a IO Data Sample RX Indicator packet."); } // payload[0] is the frame type. int index = 1; var addr = new byte[8]; Array.Copy(payload, index, addr, 0, addr.Length); // 8 bytes of 64-bit address. XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Receive options byte receiveOptions = payload[index]; index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); } return(new IODataSampleRxIndicatorPacket(sourceAddress64, sourceAddress16, receiveOptions, data)); }
/// <summary> /// Creates a /// </summary> /// <param name="packet"></param> /// <returns></returns> /// <exception cref="NotImplementedException">Thrown if device uses 802.15.4 protocol, since that functionality isn't implemented</exception> protected XBeeAPIPacket ExplToNoExpl(ExplicitRXIndicatorPacket packet) { XBee64BitAddress x64addr = packet.X64BitAddress; XBee16BitAddress x16addr = packet.X16BitAddress; XBeeAPIPacket newPacket; if (xbeeDevice.Protocol == XBeeProtocol.Byte.RAW_802_15_4) { throw new NotImplementedException("This method does not support 802.15.4 protocol yet"); } else { newPacket = new ReceivePacket(packet.X64BitAddress, packet.X16BitAddress, packet.ReceiveOptions, packet.RfData); } return(newPacket); }
/** * Class constructor. Instantiates a new {@code TransmitStatusPacket} * object with the given parameters. * * @param frameID Frame ID. * @param destAddress16 16-bit Network address the packet was delivered to. * @param tranmistRetryCount The number of application transmission retries * that took place. * @param transmitStatus Transmit status. * @param discoveryStatus Discovery status. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code tranmistRetryCount < 0} or * if {@code tranmistRetryCount > 255}. * @throws ArgumentNullException if {@code destAddress16 == null} or * if {@code transmitStatus == null} or * if {@code discoveryStatus == null}. * * @see com.digi.xbee.api.models.XBeeDiscoveryStatus * @see com.digi.xbee.api.models.XBeeTransmitStatus * @see com.digi.xbee.api.models.XBee16BitAddress */ public TransmitStatusPacket(byte frameID, XBee16BitAddress destAddress16, byte tranmistRetryCount, XBeeTransmitStatus transmitStatus, XBeeDiscoveryStatus discoveryStatus) : base(APIFrameType.TRANSMIT_STATUS) { if (destAddress16 == null) throw new ArgumentNullException("16-bit destination address cannot be null."); if (transmitStatus == null) throw new ArgumentNullException("Delivery status cannot be null."); if (discoveryStatus == null) throw new ArgumentNullException("Discovery status cannot be null."); this.frameID = frameID; this.destAddress16 = destAddress16; this.tranmistRetryCount = tranmistRetryCount; this.transmitStatus = transmitStatus; this.discoveryStatus = discoveryStatus; this.logger = LogManager.GetLogger<TransmitStatusPacket>(); }
/** * Class constructor. Instantiates a new * {@code IODataSampleRxIndicatorPacket} object with the given parameters. * * @param sourceAddress64 64-bit address of the sender. * @param sourceAddress16 16-bit address of the sender. * @param receiveOptions Receive options. * @param rfData Received RF data. * * @throws ArgumentException if {@code receiveOptions < 0} or * if {@code receiveOptions > 255} or * if {@code rfData.Length < 5}. * @throws ArgumentNullException if {@code sourceAddress64 == null} or * if {@code sourceAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeReceiveOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData) : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR) { if (sourceAddress64 == null) throw new ArgumentNullException("64-bit source address cannot be null."); if (sourceAddress16 == null) throw new ArgumentNullException("16-bit source address cannot be null."); this.sourceAddress64 = sourceAddress64; this.sourceAddress16 = sourceAddress16; this.ReceiveOptions = receiveOptions; this.RFData = rfData; if (rfData != null) IOSample = new IOSample(rfData); else IOSample = null; this.logger = LogManager.GetLogger<IODataSampleRxIndicatorPacket>(); }
/// <summary> /// Creates a new <see cref="TX16Packet"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to a TX16 Request packet (<c>0x01</c>). The byte array must be in <see cref="OperatingMode.API"/> /// mode.</param> /// <returns>Parsed TX16 Request packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.TX_16.GetValue()</c> /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static TX16Packet CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("TX16 Request packet payload cannot be null."); } // 1 (Frame type) + 1 (frame ID) + 2 (address) + 1 (transmit options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete TX16 Request packet."); } if ((payload[0] & 0xFF) != APIFrameType.TX_16.GetValue()) { throw new ArgumentException("Payload is not a TX16 Request packet."); } // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = (byte)(payload[index] & 0xFF); index = index + 1; // 2 bytes of address, starting at 2nd byte. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Transmit options byte. byte transmitOptions = (byte)(payload[index] & 0xFF); index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); } return(new TX16Packet(frameID, destAddress16, transmitOptions, data)); }
/// <summary> /// Creates a new <see cref="RX16IOPacket"/> object from the given payload. /// </summary> /// <param name="payload">The API frame payload. It must start with the frame type corresponding /// to an RX16 Address IO packet (<c>0x83</c>). The byte array must be in <see cref="OperatingMode.API"/> /// mode.</param> /// <returns>Parsed RX16 Address IO packet.</returns> /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.RX_IO_16.GetValue()</c> /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception> public static RX16IOPacket CreatePacket(byte[] payload) { if (payload == null) { throw new ArgumentNullException("RX16 Address IO packet payload cannot be null."); } // 1 (Frame type) + 2 (16-bit address) + 1 (RSSI) + 1 (receive options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) { throw new ArgumentException("Incomplete RX16 Address IO packet."); } if ((payload[0] & 0xFF) != APIFrameType.RX_IO_16.GetValue()) { throw new ArgumentException("Payload is not a RX16 Address IO packet."); } // payload[0] is the frame type. int index = 1; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Receive options byte. byte rssi = (byte)(payload[index] & 0xFF); index = index + 1; // Received Signal Strength Indicator byte. byte receiveOptions = (byte)(payload[index] & 0xFF); index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); } return(new RX16IOPacket(sourceAddress16, rssi, receiveOptions, data)); }
/// <summary> /// Class constructor. Instantiates a <see cref="IODataSampleRxIndicatorPacket"/> with the given parameters. /// </summary> /// <param name="sourceAddress64">The 64-bit address of the sender.</param> /// <param name="sourceAddress16">The 16-bit address of the sender.</param> /// <param name="receiveOptions">The receive options.</param> /// <param name="rfData">The received RF data.</param> /// <exception cref="ArgumentException">If <c><paramref name="receiveOptions"/> <![CDATA[<]]> 0</c> /// or if <c><paramref name="receiveOptions"/> <![CDATA[>]]> 255</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="sourceAddress64"/> is <c>null</c> /// or if <paramref name="sourceAddress16"/> is <c>null</c>.</exception> /// <seealso cref="XBeeReceiveOptions"/> /// <seealso cref="XBee16BitAddress"/> /// <seealso cref="XBee64BitAddress"/> public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData) : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR) { SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit source address cannot be null."); SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit source address cannot be null."); ReceiveOptions = receiveOptions; RFData = rfData; if (rfData != null && rfData.Length >= 5) { IOSample = new IOSample(rfData); } else { // TODO: Should we throw an exception here? IOSample = null; } logger = LogManager.GetLogger <IODataSampleRxIndicatorPacket>(); }
/** * Class constructor. Instantiates a new {@code RemoteATCommandRequest} * object with the given parameters. * * @param frameID The Frame ID. * @param destAddress64 64-bit address of the destination device. * @param destAddress16 16-bit address of the destination device. * @param transmitOptions Bitfield of supported transmission options. * @param command AT command. * @param parameter AT command parameter as String. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code destAddress64 == null} or * if {@code destAddress16 == null} or * if {@code command == null}. * * @see com.digi.xbee.api.models.XBeeTransmitOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16, byte transmitOptions, String command, string parameter) : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST) { ; if (destAddress64 == null) throw new ArgumentNullException("64-bit destination address cannot be null."); if (destAddress16 == null) throw new ArgumentNullException("16-bit destination address cannot be null."); if (command == null) throw new ArgumentNullException("AT command cannot be null."); this.frameID = frameID; this.destAddress64 = destAddress64; this.destAddress16 = destAddress16; this.transmitOptions = transmitOptions; this.Command = command; if (parameter != null) this.parameter = Encoding.UTF8.GetBytes(parameter); this.logger = LogManager.GetLogger<RemoteATCommandPacket>(); }
/** * Class constructor. Instantiates a new * {@code RemoteATCommandResponsePacket} object with the given parameters. * * @param frameID frame ID. * @param sourceAddress64 64-bit address of the remote radio returning * response. * @param sourceAddress16 16-bit network address of the remote. * @param command The AT command. * @param status The command status. * @param commandValue The AT command response value. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255}. * @throws ArgumentNullException if {@code sourceAddress64 == null} or * if {@code sourceAddress16 == null} or * if {@code command == null} or * if {@code status == null}. * * @see com.digi.xbee.api.models.ATCommandStatus * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteATCommandResponsePacket(byte frameID, XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, String command, ATCommandStatus status, byte[] commandValue) : base(APIFrameType.REMOTE_AT_COMMAND_RESPONSE) { if (sourceAddress64 == null) throw new ArgumentNullException("64-bit source address cannot be null."); if (sourceAddress16 == null) throw new ArgumentNullException("16-bit source address cannot be null."); if (command == null) throw new ArgumentNullException("AT command cannot be null."); if (status == null) throw new ArgumentNullException("AT command status cannot be null."); if (frameID < 0 || frameID > 255) throw new ArgumentException("Frame ID must be between 0 and 255."); this.frameID = frameID; this.sourceAddress64 = sourceAddress64; this.sourceAddress16 = sourceAddress16; this.Command = command; this.Status = status; this.commandValue = commandValue; this.logger = LogManager.GetLogger<RemoteATCommandResponsePacket>(); }
/// <summary> /// Class constructor. Instantiates a new <see cref="ExplicitRxIndicatorPacket"/> object with the /// given parameters. /// </summary> /// <param name="sourceAddress64">The 64-bit address of the sender device.</param> /// <param name="sourceAddress16">The 16-bit address of the sender device.</param> /// <param name="sourceEndpoint">The endpoint of the source that initiated the transmission.</param> /// <param name="destEndpoint">The endpoint of the destination the message was addressed to.</param> /// <param name="clusterID">The cluster ID the packet was addressed to.</param> /// <param name="profileID">The profile ID the packet was addressed to.</param> /// <param name="receiveOptions">The bitField of receive options.</param> /// <param name="rfData">The received RF data.</param> /// <exception cref="ArgumentException">If <c>profileID.Length != 2</c> /// or if <c>clusterID.Length != 2</c>.</exception> /// <exception cref="ArgumentNullException">If <c><paramref name="sourceAddress64"/> == null</c> /// or if <c><paramref name="sourceAddress16"/> == null</c>.</exception> /// <seealso cref="XBeeReceiveOptions"/> /// <seealso cref="XBee16BitAddress"/> /// <seealso cref="XBee64BitAddress"/> public ExplicitRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte sourceEndpoint, byte destEndpoint, byte[] clusterID, byte[] profileID, byte receiveOptions, byte[] rfData) : base(APIFrameType.EXPLICIT_RX_INDICATOR) { if (profileID.Length != 2) { throw new ArgumentException("Profile ID length must be 2."); } if (clusterID.Length != 2) { throw new ArgumentException("Cluster ID length must be 2."); } SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null."); SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null."); SourceEndpoint = sourceEndpoint; DestEndpoint = destEndpoint; ClusterID = clusterID; ProfileID = profileID; ReceiveOptions = receiveOptions; RFData = rfData; logger = LogManager.GetLogger <TransmitPacket>(); }
/** * Class constructor. Instantiates a new {@code RemoteXBeeDevice} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote XBee device. * @param addr64 The 64-bit address to identify this remote XBee device. * @param addr16 The 16-bit address to identify this remote XBee device. It * might be {@code null}. * @param ni The node identifier of this remote XBee device. It might be * {@code null}. * * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true}. * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteXBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, string ni) : base(localXBeeDevice, addr64, addr16, ni) { }
/** * Configures the 16-bit address (network address) of this XBee device with * the provided one. * * @param xbee16BitAddress The new 16-bit address. * * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code xbee16BitAddress == null}. * @throws TimeoutException if there is a timeout setting the address. * @throws XBeeException if there is any other XBee related exception. * * @see #get16BitAddress() * @see com.digi.xbee.api.models.XBee16BitAddress */ protected void Set16BitAddress(XBee16BitAddress xbee16BitAddress)/*throws TimeoutException, XBeeException */{ if (xbee16BitAddress == null) throw new ArgumentNullException("16-bit address canot be null."); SetParameter("MY", xbee16BitAddress.Value); this.xbee16BitAddress = xbee16BitAddress; }
/** * Class constructor. Instantiates a new {@code TransmitPacket} object * with the given parameters. * * @param frameID Frame ID. * @param destAddress64 64-bit address of the destination device. * @param destAddress16 16-bit address of the destination device. * @param broadcastRadius maximum number of hops a broadcast transmission * can occur. * @param transmitOptions Bitfield of supported transmission options. * @param rfData RF Data that is sent to the destination device. * * @throws ArgumentException if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code broadcastRadius < 0} or * if {@code broadcastRadius > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code destAddress64 == null} or * if {@code destAddress16 == null}. * * @see com.digi.xbee.api.models.XBeeTransmitOptions * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public TransmitPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16, byte broadcastRadius, byte transmitOptions, byte[] rfData) : base(APIFrameType.TRANSMIT_REQUEST) { if (destAddress64 == null) throw new ArgumentNullException("64-bit destination address cannot be null."); if (destAddress16 == null) throw new ArgumentNullException("16-bit destination address cannot be null."); this.frameID = frameID; this.destAddress64 = destAddress64; this.destAddress16 = destAddress16; this.broadcastRadius = broadcastRadius; this.transmitOptions = transmitOptions; this.RFData = rfData; this.logger = LogManager.GetLogger<TransmitPacket>(); }
/** * Creates a new remote XBee device with the provided 64-bit address, * 16-bit address, node identifier and the XBee device that is using this * data reader as the connection interface for the remote device. * * The new XBee device will be a {@code RemoteDigiMeshDevice}, * a {@code RemoteDigiPointDevice}, a {@code RemoteRaw802Device} or a * {@code RemoteZigBeeDevice} depending on the protocol of the local XBee * device. If the protocol cannot be determined or is unknown a * {@code RemoteXBeeDevice} will be created instead. * * @param addr64 The 64-bit address of the new remote device. It cannot be * {@code null}. * @param addr16 The 16-bit address of the new remote device. It may be * {@code null}. * @param ni The node identifier of the new remote device. It may be * {@code null}. * * @return a new remote XBee device with the given parameters. */ private RemoteXBeeDevice createRemoteXBeeDevice(XBee64BitAddress addr64, XBee16BitAddress addr16, String ni) { RemoteXBeeDevice device = null; switch (xbeeDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: device = new RemoteZigBeeDevice(xbeeDevice, addr64, addr16, ni); break; case XBeeProtocol.DIGI_MESH: device = new RemoteDigiMeshDevice(xbeeDevice, addr64, ni); break; case XBeeProtocol.DIGI_POINT: device = new RemoteDigiPointDevice(xbeeDevice, addr64, ni); break; case XBeeProtocol.RAW_802_15_4: device = new RemoteRaw802Device(xbeeDevice, addr64, addr16, ni); break; default: device = new RemoteXBeeDevice(xbeeDevice, addr64, addr16, ni); break; } return device; }
/** * Class constructor. Instantiates a new {@code RemoteRaw802Device} object * interface to be used. * * @param localXBeeDevice The local 802.15.4 device that will behave as * connection interface to communicate with this * remote 802.15.4 device. * @param addr16 The 16-bit address to identify this remote 802.15.4 * device. * * @throws ArgumentException if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4}. * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr16 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress */ public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee16BitAddress addr16) : base(localXBeeDevice, XBee64BitAddress.UNKNOWN_ADDRESS) { // Verify the local device has 802.15.4 protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4) throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + "."); this.xbee16BitAddress = addr16; }
/** * Creates a new {@code ReceivePacket} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Receive packet ({@code 0x90}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed ZigBee Receive packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.RECEIVE_PACKET.getValue()} or * if {@code payload.Length < {@value #MIN_API_PAYLOAD_LENGTH}} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static ReceivePacket createPacket(byte[] payload) { if (payload == null) throw new ArgumentNullException("Receive packet payload cannot be null."); // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options) if (payload.Length < MIN_API_PAYLOAD_LENGTH) throw new ArgumentException("Incomplete Receive packet."); if ((payload[0] & 0xFF) != APIFrameType.RECEIVE_PACKET.GetValue()) throw new ArgumentException("Payload is not a Receive packet."); // payload[0] is the frame type. int index = 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 2 bytes of 16-bit address. XBee64BitAddress sourceAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Receive options byte receiveOptions = payload[index]; index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); //data = Arrays.copyOfRange(payload, index, payload.Length); } return new ReceivePacket(sourceAddress64, sourceAddress16, receiveOptions, data); }
/*throws OperationNotSupportedException */ /** * Returns the remote device already contained in the network whose 16-bit * address matches the given one. * * <p>Note that this method <b>does not perform a discovery</b>, only * returns the device that has been previously discovered.</p> * * @param address The 16-bit address of the device to be retrieved. * * @return The remote device in the network or {@code null} if it is not * found. * * @throws ArgumentException if {@code address.equals(XBee16BitAddress.UNKNOWN_ADDRESS)}. * @throws ArgumentNullException if {@code address == null}. * @throws OperationNotSupportedException if the protocol of the local XBee device is DigiMesh or Point-to-Multipoint. */ public RemoteXBeeDevice GetDevice(XBee16BitAddress address) { if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_MESH) throw new OperationNotSupportedException("DigiMesh protocol does not support 16-bit addressing."); if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_POINT) throw new OperationNotSupportedException("Point-to-Multipoint protocol does not support 16-bit addressing."); if (address == null) throw new ArgumentNullException("16-bit address cannot be null."); if (address.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) throw new ArgumentNullException("16-bit address cannot be unknown."); logger.DebugFormat("{0}Getting device '{1}' from network.", localDevice.ToString(), address); // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'addRemoteDevice' method. RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. ICollection<RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(address)) { devInNetwork = d; break; } } // Look in the 16-bit map. if (devInNetwork == null) devInNetwork = remotesBy16BitAddr[address]; return devInNetwork; }
/** * Parses the given node discovery API data to create and return a remote * XBee Device. * * @param data Byte array with the data to parse. * @param localDevice The local device that received the remote XBee data. * * @return Discovered XBee device. */ private async Task<RemoteXBeeDevice> ParseDiscoveryAPIData(byte[] data, XBeeDevice localDevice) { if (data == null) return null; RemoteXBeeDevice device = null; XBee16BitAddress addr16 = null; XBee64BitAddress addr64 = null; String id = null; // TODO role of the device: coordinator, router, end device or unknown. //XBeeDeviceType role = XBeeDeviceType.UNKNOWN; int signalStrength = 0; byte[] profileID = null; byte[] manufacturerID = null; using (var inputStream = new MemoryStream(data)) { // Read 16 bit address. addr16 = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // Read 64 bit address. addr64 = new XBee64BitAddress(await ByteUtils.ReadBytes(8, inputStream)); switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: case XBeeProtocol.DIGI_MESH: case XBeeProtocol.ZNET: case XBeeProtocol.DIGI_POINT: case XBeeProtocol.XLR: // TODO [XLR_DM] The next version of the XLR will add DigiMesh support. // For the moment only point-to-multipoint is supported in this kind of devices. case XBeeProtocol.XLR_DM: // Read node identifier. id = ByteUtils.ReadString(inputStream); // Read parent address. XBee16BitAddress parentAddress = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // TODO Read device type. //role = XBeeDeviceType.get(inputStream.read()); // Consume status byte, it is not used yet. await ByteUtils.ReadBytes(1, inputStream); // Read profile ID. profileID = await ByteUtils.ReadBytes(2, inputStream); // Read manufacturer ID. manufacturerID = await ByteUtils.ReadBytes(2, inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], parent[{5}], profile[{6}], manufacturer[{7}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, parentAddress, HexUtils.ByteArrayToHexString(profileID), HexUtils.ByteArrayToHexString(manufacturerID)); break; case XBeeProtocol.RAW_802_15_4: // Read strength signal byte. signalStrength = inputStream.ReadByte(); // Read node identifier. id = ByteUtils.ReadString(inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], rssi[{5}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, signalStrength); break; case XBeeProtocol.UNKNOWN: default: logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64); break; } // Create device and fill with parameters. switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: device = new RemoteZigBeeDevice(localDevice, addr64, addr16, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_MESH: device = new RemoteDigiMeshDevice(localDevice, addr64, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_POINT: device = new RemoteDigiPointDevice(localDevice, addr64, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.RAW_802_15_4: device = new RemoteRaw802Device(localDevice, addr64, addr16, id/*, role*/); // TODO signalStrength break; default: device = new RemoteXBeeDevice(localDevice, addr64, addr16, id/*, role*/); break; } } return device; }
/** * Creates a new {@code TransmitStatusPacket} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Transmit Status packet ({@code 0x8B}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed Transmit Status packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.TRANSMIT_STATUS.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code tranmistRetryCount < 0} or * if {@code tranmistRetryCount > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static TransmitStatusPacket createPacket(byte[] payload) { if (payload == null) throw new ArgumentNullException("Transmit Status packet payload cannot be null."); // 1 (Frame type) + 1 (frame ID) + 2 (16-bit address) + 1 (retry count) + 1 (delivery status) + 1 (discovery status) if (payload.Length < MIN_API_PAYLOAD_LENGTH) throw new ArgumentException("Incomplete Transmit Status packet."); if ((payload[0] & 0xFF) != APIFrameType.TRANSMIT_STATUS.GetValue()) throw new ArgumentException("Payload is not a Transmit Status packet."); // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; // 2 bytes of 16-bit address. XBee16BitAddress address = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Retry count byte. byte retryCount = payload[index]; index = index + 1; // Delivery status byte. byte deliveryStatus = payload[index]; index = index + 1; // Discovery status byte. byte discoveryStatus = payload[index]; // TODO if XBeeTransmitStatus is unknown???? return new TransmitStatusPacket(frameID, address, retryCount, XBeeTransmitStatus.SUCCESS.Get(deliveryStatus), XBeeDiscoveryStatus.DISCOVERY_STATUS_ADDRESS_AND_ROUTE.Get(discoveryStatus)); }
/*throws TimeoutException, XBeeException */ /** * Sends the provided data to the XBee device of the network corresponding * to the given 64-bit/16-bit address. * * <p>This method blocks till a success or error response arrives or the * configured receive timeout expires.</p> * * <p>The received timeout is configured using the {@code setReceiveTimeout} * method and can be consulted with {@code getReceiveTimeout} method.</p> * * <p>For non-blocking operations use the method * {@link #sendDataAsync(XBee64BitAddress, XBee16BitAddress, byte[])}.</p> * * @param address64Bit The 64-bit address of the XBee that will receive the * data. * @param address16bit The 16-bit address of the XBee that will receive the * data. If it is unknown the * {@code XBee16BitAddress.UNKNOWN_ADDRESS} must be * used. * @param data Byte array containing the data to be sent. * * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code address64Bit == null} or * if {@code address16bit == null} or * if {@code data == null}. * @throws TimeoutException if there is a timeout sending the data. * @throws XBeeException if a remote device is trying to send data or * if there is any other XBee related exception. * * @see #getReceiveTimeout() * @see #setReceiveTimeout(int) * @see #sendData(RemoteXBeeDevice, byte[]) * @see #sendData(XBee64BitAddress, byte[]) * @see #sendDataAsync(RemoteXBeeDevice, byte[]) * @see #sendDataAsync(XBee64BitAddress, byte[]) * @see #sendDataAsync(XBee64BitAddress, XBee16BitAddress, byte[]) * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ protected void SendData(XBee64BitAddress address64Bit, XBee16BitAddress address16bit, byte[] data) { // Verify the parameters are not null, if they are null, throw an exception. if (address64Bit == null) throw new ArgumentNullException("64-bit address cannot be null"); if (address16bit == null) throw new ArgumentNullException("16-bit address cannot be null"); if (data == null) throw new ArgumentNullException("Data cannot be null"); // Check connection. if (!connectionInterface.SerialPort.IsOpen) throw new InterfaceNotOpenException(); // Check if device is remote. if (IsRemote) throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device."); logger.DebugFormat(ToString() + "Sending data to {0}[{1}] >> {2}.", address64Bit, address16bit, HexUtils.PrettyHexString(data)); XBeePacket xbeePacket = new TransmitPacket(GetNextFrameID(), address64Bit, address16bit, 0, (byte)XBeeTransmitOptions.NONE, data); SendAndCheckXBeePacket(xbeePacket, false); }
/** * Class constructor. Instantiates a new {@code RemoteZigBeeDevice} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote ZigBee device. * @param addr64 The 64-bit address to identify this remote ZigBee device. * @param addr16 The 16-bit address to identify this remote ZigBee device. * It might be {@code null}. * @param ni The node identifier of this remote ZigBee device. It might be * {@code null}. * * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or * if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.ZIGBEE}. * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public RemoteZigBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, string ni) : base(localXBeeDevice, addr64, addr16, ni) { // Verify the local device has ZigBee protocol. if (localXBeeDevice.XBeeProtocol != XBeeProtocol.ZIGBEE) throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.ZIGBEE.GetDescription() + "."); }
/** * Updates the current device reference with the data provided for the * given device. * * <p><b>This is only for internal use.</b></p> * * @param device The XBee Device to get the data from. */ public void UpdateDeviceDataFrom(AbstractXBeeDevice device) { // TODO Should the devices have the same protocol?? // TODO Should be allow to update a local from a remote or viceversa?? Maybe // this must be in the Local/Remote device class(es) and not here... // Only update the Node Identifier if the provided is not null. if (device.NodeID != null) this.nodeID = device.NodeID; // Only update the 64-bit address if the original is null or unknown. XBee64BitAddress addr64 = device.Get64BitAddress(); if (addr64 != null && addr64 != XBee64BitAddress.UNKNOWN_ADDRESS && !addr64.Equals(xbee64BitAddress) && (xbee64BitAddress == null || xbee64BitAddress.Equals(XBee64BitAddress.UNKNOWN_ADDRESS))) { xbee64BitAddress = addr64; } // TODO Change here the 16-bit address or maybe in ZigBee and 802.15.4? // TODO Should the 16-bit address be always updated? Or following the same rule as the 64-bit address. XBee16BitAddress addr16 = device.Get16BitAddress(); if (addr16 != null && !addr16.Equals(xbee16BitAddress)) { xbee16BitAddress = addr16; } //this.deviceType = device.deviceType; // This is not yet done. // The operating mode: only API/API2. Do we need this for a remote device? // The protocol of the device should be the same. // The hardware version should be the same. // The firmware version can change... }
/** * Class constructor. Instantiates a new {@code RemoteRaw802Device} object * with the given local {@code Raw802Device} which contains the connection * interface to be used. * * @param localXBeeDevice The local 802.15.4 device that will behave as * connection interface to communicate with this * remote 802.15.4 device. * @param addr16 The 16-bit address to identify this remote 802.15.4 * device. * * @throws ArgumentNullException if {@code localXBeeDevice == null} or * if {@code addr16 == null}. * * @see com.digi.xbee.api.models.XBee16BitAddress */ public RemoteRaw802Device(Raw802Device localXBeeDevice, XBee16BitAddress addr16) : base(localXBeeDevice, XBee64BitAddress.UNKNOWN_ADDRESS) { this.xbee16BitAddress = addr16; }
/** * Reads some parameters from this device and obtains its protocol. * * <p>This method refresh the values of:</p> * <ul> * <li>64-bit address only if it is not initialized.</li> * <li>Node Identifier.</li> * <li>Hardware version if it is not initialized.</li> * <li>Firmware version.</li> * <li>XBee device protocol.</li> * <li>16-bit address (not for DigiMesh modules).</li> * </ul> * * @throws InterfaceNotOpenException if this device connection is not open. * @throws TimeoutException if there is a timeout reading the parameters. * @throws XBeeException if there is any other XBee related exception. * * @see #get16BitAddress() * @see #get64BitAddress() * @see #getHardwareVersion() * @see #getNodeID() * @see #getFirmwareVersion() * @see #getXBeeProtocol() * @see #setNodeID(String) */ public void readDeviceInfo() /*throws TimeoutException, XBeeException*/ { byte[] response = null; // Get the 64-bit address. if (xbee64BitAddress == null || xbee64BitAddress == XBee64BitAddress.UNKNOWN_ADDRESS) { String addressHigh; String addressLow; response = GetParameter("SH"); addressHigh = HexUtils.ByteArrayToHexString(response); response = GetParameter("SL"); addressLow = HexUtils.ByteArrayToHexString(response); while (addressLow.Length < 8) addressLow = "0" + addressLow; xbee64BitAddress = new XBee64BitAddress(addressHigh + addressLow); } // Get the Node ID. response = GetParameter("NI"); nodeID = Encoding.UTF8.GetString(response); // Get the hardware version. if (hardwareVersion == null) { response = GetParameter("HV"); hardwareVersion = HardwareVersion.Get(response[0]); } // Get the firmware version. response = GetParameter("VR"); firmwareVersion = HexUtils.ByteArrayToHexString(response); // Obtain the device protocol. XBeeProtocol = XBeeProtocol.UNKNOWN.DetermineProtocol(hardwareVersion, firmwareVersion); // Get the 16-bit address. This must be done after obtaining the protocol because // DigiMesh and Point-to-Multipoint protocols don't have 16-bit addresses. if (XBeeProtocol != XBeeProtocol.DIGI_MESH && XBeeProtocol != XBeeProtocol.DIGI_POINT) { response = GetParameter("MY"); xbee16BitAddress = new XBee16BitAddress(response); } }
/** * Creates an new {@code RemoteATCommandResponsePacket} object from the * given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Remote AT Command Response packet ({@code 0x97}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed Remote AT Command Response packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.REMOTE_AT_COMMAND_RESPONSE.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code frameID < 0} or * if {@code frameID > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static RemoteATCommandResponsePacket createPacket(byte[] payload) { if (payload == null) throw new ArgumentNullException("Remote AT Command Response packet payload cannot be null."); // 1 (Frame type) + 1 (frame ID) + 8 (32-bit address) + 2 (16-bit address) + 2 (AT command) + 1 (status) if (payload.Length < MIN_API_PAYLOAD_LENGTH) throw new ArgumentException("Incomplete Remote AT Command Response packet."); if ((payload[0] & 0xFF) != APIFrameType.REMOTE_AT_COMMAND_RESPONSE.GetValue()) throw new ArgumentException("Payload is not a Remote AT Command Response packet."); // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; var addr = new byte[8]; Array.Copy(payload, index, addr, 0, addr.Length); // 8 bytes of 64-bit address. XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // 2 bytes of AT command. string command = Encoding.UTF8.GetString(new byte[] { payload[index], payload[index + 1] }); index = index + 2; // Status byte. byte status = payload[index]; index = index + 1; // Get data. byte[] commandData = null; if (index < payload.Length) { commandData = new byte[payload.Length - index]; Array.Copy(payload, index, commandData, 0, commandData.Length); //commandData = Arrays.copyOfRange(payload, index, payload.Length); } // TODO if ATCommandStatus is unknown???? return new RemoteATCommandResponsePacket(frameID, sourceAddress64, sourceAddress16, command, ATCommandStatus.UNKNOWN.Get(status), commandData); }
/** * Class constructor. Instantiates a new {@code RemoteXBeeDevice} object * with the given local {@code XBeeDevice} which contains the connection * interface to be used. * * @param localXBeeDevice The local XBee device that will behave as * connection interface to communicate with this * remote XBee device. * @param addr64 The 64-bit address to identify this XBee device. * @param addr16 The 16-bit address to identify this XBee device. It might * be {@code null}. * @param id The node identifier of this XBee device. It might be * {@code null}. * * @throws ArgumentException If {@code localXBeeDevice.isRemote() == true}. * @throws ArgumentNullException If {@code localXBeeDevice == null} or * if {@code addr64 == null}. * * @see #AbstractXBeeDevice(IConnectionInterface) * @see #AbstractXBeeDevice(String, int) * @see #AbstractXBeeDevice(String, SerialPortParameters) * @see #AbstractXBeeDevice(XBeeDevice, XBee64BitAddress) * @see #AbstractXBeeDevice(String, int, int, int, int, int) * @see com.digi.xbee.api.models.XBee16BitAddress * @see com.digi.xbee.api.models.XBee64BitAddress */ public AbstractXBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, XBee16BitAddress addr16, String id) { if (localXBeeDevice == null) throw new ArgumentNullException("Local XBee device cannot be null."); if (addr64 == null) throw new ArgumentNullException("XBee 64-bit address of the device cannot be null."); if (localXBeeDevice.IsRemote) throw new ArgumentException("The given local XBee device is remote."); XBeeProtocol = XBeeProtocol.UNKNOWN; this.localXBeeDevice = localXBeeDevice; this.connectionInterface = localXBeeDevice.GetConnectionInterface(); this.xbee64BitAddress = addr64; this.xbee16BitAddress = addr16; if (addr16 == null) xbee16BitAddress = XBee16BitAddress.UNKNOWN_ADDRESS; this.nodeID = id; this.logger = LogManager.GetLogger(this.GetType()); logger.DebugFormat(ToString() + "Using the connection interface {0}.", connectionInterface.GetType().Name); this.IOPacketReceiveListener = new CustomPacketReceiveListener(this); }
/*throws XBeeException */ /** * Sends the provided data to the XBee device of the network corresponding * to the given 16-bit address asynchronously. * * <p>Asynchronous transmissions do not wait for answer from the remote * device or for transmit status packet</p> * * @param address The 16-bit address of the XBee that will receive the data. * @param data Byte array containing data to be sent. * * @throws InterfaceNotOpenException if the device is not open. * @throws ArgumentNullException if {@code address == null} or * if {@code data == null}. * @throws XBeeException if there is any XBee related exception. * * @see com.digi.xbee.api.models.XBee16BitAddress * @see #sendData(RemoteXBeeDevice, byte[]) * @see #sendData(XBee16BitAddress, byte[]) * @see #sendData(XBee64BitAddress, byte[]) * @see #sendDataAsync(RemoteXBeeDevice, byte[]) * @see #sendDataAsync(XBee64BitAddress, byte[]) */ public void SendDataAsync(XBee16BitAddress address, byte[] data) { // Verify the parameters are not null, if they are null, throw an exception. if (address == null) throw new ArgumentNullException("Address cannot be null"); if (data == null) throw new ArgumentNullException("Data cannot be null"); // Check connection. if (!connectionInterface.SerialPort.IsOpen) throw new InterfaceNotOpenException(); // Check if device is remote. if (IsRemote) throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device."); logger.InfoFormat(ToString() + "Sending data asynchronously to {0} >> {1}.", address, HexUtils.PrettyHexString(data)); XBeePacket xbeePacket = new TX16Packet(GetNextFrameID(), address, (byte)XBeeTransmitOptions.NONE, data); SendAndCheckXBeePacket(xbeePacket, true); }
/** * Creates a new {@code TransmitPacket} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Transmit packet ({@code 0x10}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed Transmit Request packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.TRANSMIT_REQUEST.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code broadcastRadius < 0} or * if {@code broadcastRadius > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static TransmitPacket createPacket(byte[] payload) { Contract.Requires<ArgumentNullException>(payload != null, "Transmit packet payload cannot be null."); // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (broadcast radious) + 1 (options) Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete Transmit packet."); Contract.Requires<ArgumentException>((payload[0] & 0xFF) != APIFrameType.TRANSMIT_REQUEST.GetValue(), "Payload is not a Transmit packet."); // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 8 bytes of 64-bit address. XBee64BitAddress destAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Broadcast radious byte. byte broadcastRadius = payload[index]; index = index + 1; // Options byte. byte options = payload[index]; index = index + 1; // Get RF data. byte[] rfData = null; if (index < payload.Length) { rfData = new byte[payload.Length - index]; Array.Copy(payload, index, rfData, 0, rfData.Length); //rfData = Arrays.copyOfRange(payload, index, payload.Length); } return new TransmitPacket(frameID, destAddress64, destAddress16, broadcastRadius, options, rfData); }
/** * Creates a new {@code IODataSampleRxIndicatorPacket} object from the * given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a IO Data Sample RX Indicator packet ({@code 0x92}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed ZigBee Receive packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255} or * if {@code rfData.Length < 5}. * @throws ArgumentNullException if {@code payload == null}. */ public static IODataSampleRxIndicatorPacket CreatePacket(byte[] payload) { Contract.Requires<ArgumentNullException>(payload != null, "IO Data Sample RX Indicator packet payload cannot be null."); // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options) Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete IO Data Sample RX Indicator packet."); Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue(), "Payload is not a IO Data Sample RX Indicator packet."); // payload[0] is the frame type. int index = 1; var addr = new byte[8]; Array.Copy(payload, index, addr, 0, addr.Length); // 2 bytes of 16-bit address. XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Receive options byte receiveOptions = payload[index]; index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); //data = Arrays.copyOfRange(payload, index, payload.Length); } return new IODataSampleRxIndicatorPacket(sourceAddress64, sourceAddress16, receiveOptions, data); }
/** * Creates a new {@code RX16Packet} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a RX16 packet ({@code 0x81}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed RX 16 packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.RX_16.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code rssi < 0} or * if {@code rssi > 100} or * if {@code receiveOptions < 0} or * if {@code receiveOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static RX16Packet CreatePacket(byte[] payload) { Contract.Requires<ArgumentNullException>(payload != null, "RX16 packet payload cannot be null."); // 1 (Frame type) + 2 (16-bit address) + 1 (signal strength) + 1 (receive options) Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete RX16 packet."); Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.RX_16.GetValue(), "Payload is not a RX16 packet."); // payload[0] is the frame type. int index = 1; // 2 bytes of 16-bit address. XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Signal strength byte. byte signalStrength = (byte)(payload[index] & 0xFF); index = index + 1; // Receive options byte. byte receiveOptions = (byte)(payload[index] & 0xFF); index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); //data = Arrays.copyOfRange(payload, index, payload.Length); } return new RX16Packet(sourceAddress16, signalStrength, receiveOptions, data); }
/** * Creates a new {@code TX16Packet} object from the given payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a TX16 Request packet ({@code 0x01}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed TX (transmit) 16 Request packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.TX_16.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static TX16Packet CreatePacket(byte[] payload) { Contract.Requires<ArgumentNullException>(payload != null, "TX16 Request packet payload cannot be null."); // 1 (Frame type) + 1 (frame ID) + 2 (address) + 1 (transmit options) Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete TX16 Request packet."); Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.TX_16.GetValue(), "Payload is not a TX16 Request packet."); // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = (byte)(payload[index] & 0xFF); index = index + 1; // 2 bytes of address, starting at 2nd byte. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Transmit options byte. byte transmitOptions = (byte)(payload[index] & 0xFF); index = index + 1; // Get data. byte[] data = null; if (index < payload.Length) { data = new byte[payload.Length - index]; Array.Copy(payload, index, data, 0, data.Length); //data = Arrays.copyOfRange(payload, index, payload.Length); } return new TX16Packet(frameID, destAddress16, transmitOptions, data); }
/** * Creates a new {@code RemoteATCommandPacket} object from the given * payload. * * @param payload The API frame payload. It must start with the frame type * corresponding to a Remote AT Command packet ({@code 0x17}). * The byte array must be in {@code OperatingMode.API} mode. * * @return Parsed Remote AT Command Request packet. * * @throws ArgumentException if {@code payload[0] != APIFrameType.REMOTE_AT_COMMAND_REQUEST.getValue()} or * if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or * if {@code frameID < 0} or * if {@code frameID > 255} or * if {@code transmitOptions < 0} or * if {@code transmitOptions > 255}. * @throws ArgumentNullException if {@code payload == null}. */ public static RemoteATCommandPacket createPacket(byte[] payload) { Contract.Requires<ArgumentNullException>(payload != null, "Remote AT Command packet payload cannot be null."); // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (transmit options byte) + 2 (AT command) Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete Remote AT Command packet."); Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue(), "Payload is not a Remote AT Command packet."); // payload[0] is the frame type. int index = 1; // Frame ID byte. byte frameID = payload[index]; index = index + 1; var array = new byte[8]; Array.Copy(payload, index, array, 0, array.Length); // 8 bytes of 64-bit address. XBee64BitAddress destAddress64 = new XBee64BitAddress(array); index = index + 8; // 2 bytes of 16-bit address. XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]); index = index + 2; // Options byte. byte transmitOptions = payload[index]; index = index + 1; // 2 bytes of AT command. string command = Encoding.UTF8.GetString(new byte[] { payload[index], payload[index + 1] }); index = index + 2; // Get data. byte[] parameterData = null; if (index < payload.Length) { parameterData = new byte[payload.Length - index]; Array.Copy(payload, index, parameterData, 0, parameterData.Length); //parameterData = Arrays.copyOfRange(payload, index, payload.Length); } return new RemoteATCommandPacket(frameID, destAddress64, destAddress16, transmitOptions, command, parameterData); }