internal virtual void HandleFrame(KnxFrame frame) { _heartbeatMonitor.Reset(); switch (frame.ServiceType) { case KnxHelper.ServiceType.SearchRequest: break; case KnxHelper.ServiceType.SearchResponse: break; case KnxHelper.ServiceType.DescriptionRequest: break; case KnxHelper.ServiceType.DescriptionResponse: break; case KnxHelper.ServiceType.ConnectRequest: break; case KnxHelper.ServiceType.ConnectResponse: var connectResponse = (ConnectResponseFrame)frame; if (connectResponse.IsValid) { IndividualAddress = connectResponse.IndividualAddress; Connected = true; SetSequenceNumber(0); ChannelId = connectResponse.ChannelId; OnConnected?.Invoke(this, EventArgs.Empty); } else { OnDisconnected?.Invoke(this, EventArgs.Empty); Connected = false; } break; case KnxHelper.ServiceType.ConnectionstateRequest: break; case KnxHelper.ServiceType.ConnectionstateResponse: break; case KnxHelper.ServiceType.DisconnectRequest: SendFrame(new DisconnectResponseFrame(this)); Connected = false; OnDisconnected?.Invoke(this, EventArgs.Empty); break; case KnxHelper.ServiceType.DisconnectResponse: break; case KnxHelper.ServiceType.DeviceConfigurationRequest: break; case KnxHelper.ServiceType.DeviceConfigurationAck: break; case KnxHelper.ServiceType.TunnellingRequest: var p = (TunnelingRequestFrame)frame; var ack = new TunnelingAckFrame(this, p.FrameSequenceNumber); SendFrame(ack); if (KnxHelper.ProcessCemi(p.Datagram, p.CemiPacket)) { OnDatagramReceived?.Invoke(this, new KnxDatgramEventArgs(p.Datagram)); } break; case KnxHelper.ServiceType.TunnellingAck: break; case KnxHelper.ServiceType.RoutingIndication: break; case KnxHelper.ServiceType.RoutingLostMessage: break; case KnxHelper.ServiceType.SecureWrapper: break; case KnxHelper.ServiceType.SessionRequest: break; case KnxHelper.ServiceType.SessionResponse: break; case KnxHelper.ServiceType.SessionAuthenticate: break; case KnxHelper.ServiceType.SessionStatus: break; case KnxHelper.ServiceType.TimerNotify: break; case KnxHelper.ServiceType.Unknown: break; } }
private void BeginReceiveCallback(object sender, SocketAsyncEventArgs args) { if (!IsListening) { return; } try { // No bytes been transferred from this async operation if (args.BytesTransferred <= 0) { DnlDebugger.LogMessage("0 bytes transferred from receive operation: " + args.RemoteEndPoint.ToString() + " | " + args.BytesTransferred, true); } else { ushort protocolId; ushort operationCode; // Parse and validate protocol id and operation code if ((protocolId = unchecked (BitConverter.ToUInt16(args.Buffer, 0))) != ProtocolId) { throw new Exception("Received datagram with different protocol id then expected. Either set your protocol id or ensure network traffic is from known clients."); } if (!OperationCodes.ReceivePacket.ContainsKey(operationCode = unchecked (BitConverter.ToUInt16(args.Buffer, 2)))) { throw new Exception("Received datagram with different unregistered operation code. Either register your operation packet handler or ensure network traffic is from known clients."); } int payloadLength = args.BytesTransferred - (sizeof(ushort) * 2); byte[] payload = new byte[payloadLength]; // Parse payload from datagram Buffer.BlockCopy(args.Buffer, 4, payload, 0, payloadLength); // Parse ip and port from endpoint string string[] systemAddress = !string.IsNullOrEmpty(args.RemoteEndPoint.ToString()) ? args.RemoteEndPoint.ToString().Split(':') : throw new Exception("Internal issue trying to parse remote endpoint from incoming datagram. Contact support"); // Invoke the on received event OnDatagramReceived?.Invoke(this, new DatagramReceivedEventArgs( systemAddress[0], int.Parse(systemAddress[1]), protocolId, operationCode, payload, payload.Length, DateTime.Now)); } } catch (Exception e) { DnlDebugger.LogMessage("Caught exception in EndReceive: " + e.Message + " | " + e.TargetSite.ToString(), true); } finally { args.Dispose(); BeginReceive(); } }