/// <summary> /// Dispatches the received XBee packet to the corresponding event handler(s). /// </summary> /// <param name="packet">The received XBee packet to be dispatched to the corresponding event /// handlers.</param> /// <seealso cref="XBeeAPIPacket"/> /// <seealso cref="XBeePacket"/> private void PacketReceived(XBeePacket packet) { // Add the packet to the packets queue. XBeePacketsQueue.AddPacket(packet); // Notify that a packet has been received to the corresponding event handlers. NotifyPacketReceived(packet); // Check if the packet is an API packet. if (!(packet is XBeeAPIPacket)) { return; } // Get the API packet type. XBeeAPIPacket apiPacket = (XBeeAPIPacket)packet; APIFrameType apiType = apiPacket.FrameType; try { // Obtain the remote device from the packet. RemoteXBeeDevice remoteDevice = GetRemoteXBeeDeviceFromPacket(apiPacket); byte[] data = null; switch (apiType) { case APIFrameType.RECEIVE_PACKET: ReceivePacket receivePacket = (ReceivePacket)apiPacket; data = receivePacket.RFData; NotifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast)); break; case APIFrameType.RX_64: RX64Packet rx64Packet = (RX64Packet)apiPacket; data = rx64Packet.RFData; NotifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast)); break; case APIFrameType.RX_16: RX16Packet rx16Packet = (RX16Packet)apiPacket; data = rx16Packet.RFData; NotifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast)); break; case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR: IODataSampleRxIndicatorPacket ioSamplePacket = (IODataSampleRxIndicatorPacket)apiPacket; NotifyIOSampleReceived(remoteDevice, ioSamplePacket.IOSample); break; case APIFrameType.RX_IO_64: RX64IOPacket rx64IOPacket = (RX64IOPacket)apiPacket; NotifyIOSampleReceived(remoteDevice, rx64IOPacket.IoSample); break; case APIFrameType.RX_IO_16: RX16IOPacket rx16IOPacket = (RX16IOPacket)apiPacket; NotifyIOSampleReceived(remoteDevice, rx16IOPacket.IoSample); break; case APIFrameType.MODEM_STATUS: ModemStatusPacket modemStatusPacket = (ModemStatusPacket)apiPacket; NotifyModemStatusReceived(modemStatusPacket.Status); break; case APIFrameType.EXPLICIT_RX_INDICATOR: ExplicitRxIndicatorPacket explicitDataPacket = (ExplicitRxIndicatorPacket)apiPacket; byte sourceEndpoint = explicitDataPacket.SourceEndpoint; byte destEndpoint = explicitDataPacket.DestEndpoint; byte[] clusterID = explicitDataPacket.ClusterID; byte[] profileID = explicitDataPacket.ProfileID; data = explicitDataPacket.RFData; // If this is an explicit packet for data transmissions in the Digi profile, // notify also the data event handler and add a Receive packet to the queue. if (sourceEndpoint == ExplicitRxIndicatorPacket.DATA_ENDPOINT && destEndpoint == ExplicitRxIndicatorPacket.DATA_ENDPOINT && clusterID.SequenceEqual(ExplicitRxIndicatorPacket.DATA_CLUSTER) && profileID.SequenceEqual(ExplicitRxIndicatorPacket.DIGI_PROFILE)) { NotifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast)); XBeePacketsQueue.AddPacket(new ReceivePacket(explicitDataPacket.SourceAddress64, explicitDataPacket.SourceAddress16, explicitDataPacket.ReceiveOptions, explicitDataPacket.RFData)); } NotifyExplicitDataReceived(new ExplicitXBeeMessage(remoteDevice, sourceEndpoint, destEndpoint, clusterID, profileID, data, explicitDataPacket.IsBroadcast)); break; case APIFrameType.USER_DATA_RELAY_OUTPUT: UserDataRelayOutputPacket relayPacket = (UserDataRelayOutputPacket)apiPacket; NotifyUserDataRelayReceived(new UserDataRelayMessage(relayPacket.SourceInterface, relayPacket.Data)); break; case APIFrameType.RX_IPV4: RXIPv4Packet rxIPv4Packet = (RXIPv4Packet)apiPacket; NotifyIPDataReceived(new IPMessage( rxIPv4Packet.SourceAddress, rxIPv4Packet.SourcePort, rxIPv4Packet.DestPort, rxIPv4Packet.Protocol, rxIPv4Packet.Data)); break; case APIFrameType.RX_SMS: RXSMSPacket rxSMSPacket = (RXSMSPacket)apiPacket; NotifySMSReceived(new SMSMessage(rxSMSPacket.PhoneNumber, rxSMSPacket.Data)); break; default: break; } } catch (XBeeException e) { logger.Error(e.Message, e); } }
/// <summary> /// Parses the given API payload to get the right API packet, depending on its API /// type (<c><paramref name="payload"/>[0]</c>). /// </summary> /// <param name="payload">The payload of the API frame.</param> /// <returns>The corresponding API packet or <see cref="UnknownXBeePacket"/> if the frame API /// type is unknown.</returns> /// <exception cref="InvalidPacketException">If the payload is invalid for the specified /// frame type.</exception> /// <seealso cref="APIFrameType"/> /// <seealso cref="XBeePacket"/> private XBeePacket ParsePayload(byte[] payload) { // Get the API frame type. APIFrameType apiType = APIFrameType.UNKNOWN.Get(payload[0]); // Parse API payload depending on API ID. XBeePacket packet = null; switch (apiType) { case APIFrameType.TX_64: packet = TX64Packet.CreatePacket(payload); break; case APIFrameType.TX_16: packet = TX16Packet.CreatePacket(payload); break; case APIFrameType.BLE_UNLOCK: packet = BluetoothUnlockPacket.CreatePacket(payload); break; case APIFrameType.USER_DATA_RELAY: packet = UserDataRelayPacket.CreatePacket(payload); break; case APIFrameType.AT_COMMAND: packet = ATCommandPacket.CreatePacket(payload); break; case APIFrameType.AT_COMMAND_QUEUE: packet = ATCommandQueuePacket.CreatePacket(payload); break; case APIFrameType.TRANSMIT_REQUEST: packet = TransmitPacket.CreatePacket(payload); break; case APIFrameType.EXPLICIT_ADDRESSING_COMMAND_FRAME: packet = ExplicitAddressingPacket.CreatePacket(payload); break; case APIFrameType.REMOTE_AT_COMMAND_REQUEST: packet = RemoteATCommandPacket.CreatePacket(payload); break; case APIFrameType.TX_SMS: packet = TXSMSPacket.CreatePacket(payload); break; case APIFrameType.TX_IPV4: packet = TXIPv4Packet.CreatePacket(payload); break; case APIFrameType.TX_REQUEST_TLS_PROFILE: packet = TXTLSProfilePacket.CreatePacket(payload); break; case APIFrameType.RX_64: packet = RX64Packet.CreatePacket(payload); break; case APIFrameType.RX_16: packet = RX16Packet.CreatePacket(payload); break; case APIFrameType.RX_IO_64: packet = RX64IOPacket.CreatePacket(payload); break; case APIFrameType.RX_IO_16: packet = RX16IOPacket.CreatePacket(payload); break; case APIFrameType.AT_COMMAND_RESPONSE: packet = ATCommandResponsePacket.CreatePacket(payload); break; case APIFrameType.TX_STATUS: packet = TXStatusPacket.CreatePacket(payload); break; case APIFrameType.MODEM_STATUS: packet = ModemStatusPacket.CreatePacket(payload); break; case APIFrameType.TRANSMIT_STATUS: packet = TransmitStatusPacket.CreatePacket(payload); break; case APIFrameType.RECEIVE_PACKET: packet = ReceivePacket.CreatePacket(payload); break; case APIFrameType.EXPLICIT_RX_INDICATOR: packet = ExplicitRxIndicatorPacket.CreatePacket(payload); break; case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR: packet = IODataSampleRxIndicatorPacket.CreatePacket(payload); break; case APIFrameType.REMOTE_AT_COMMAND_RESPONSE: packet = RemoteATCommandResponsePacket.CreatePacket(payload); break; case APIFrameType.RX_SMS: packet = RXSMSPacket.CreatePacket(payload); break; case APIFrameType.BLE_UNLOCK_RESPONSE: packet = BluetoothUnlockResponsePacket.CreatePacket(payload); break; case APIFrameType.USER_DATA_RELAY_OUTPUT: packet = UserDataRelayOutputPacket.CreatePacket(payload); break; case APIFrameType.RX_IPV4: packet = RXIPv4Packet.CreatePacket(payload); break; case APIFrameType.UNKNOWN: default: packet = UnknownXBeePacket.CreatePacket(payload); break; } return(packet); }