/// <summary> /// HerzschlagRequest der Verbindung /// </summary> /// Sendet zyklich ein Telegramm an das Gateway dass die Verbindung noch aktiv ist internal void Heartbeat() { try { if (ConnectionState != KnxConnectionState.connected) // Upps, da stimmt was mit der Verbindung nicht { HandleWrongConnectionState(); } if (ConnectionState == KnxConnectionState.connected) { KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this); Tele.SetHeartbeatTelegramm(); byte[] TeleBytes = Tele.bytes; // KnxNetForm Debug("H>:" + KnxTools.BytesToString(TeleBytes)); udpClient.Send(TeleBytes, TeleBytes.Length); ConnectionState = KnxConnectionState.hbReq; } else { Err("Err: Heartbeat: State =" + ConnectionState.ToString()); } } catch (Exception e) { Err("Err: Heartbeat: " + e.ToString()); } return; }
/// <summary> /// Schließen der Verbindung /// </summary> /// <returns>Rückgabewert true bedeutet die Verbindung konnte geschlossen werden</returns> public bool Close() { try { KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this); Tele.SetDisconnectTelegramm(); byte[] TeleBytes = Tele.bytes; //KnxNetForm.tb_Log.AppendText(Environment.NewLine + "C>:" + KnxTools.BytesToString(TeleBytes)); Debug("C>:" + KnxTools.BytesToString(TeleBytes)); udpClient.Send(TeleBytes, TeleBytes.Length); ConnectionState = KnxConnectionState.disConReq; // Warten auf Antwort, maximal OpenTimeout Sekunden int i = 0; while ((i < 10 * OpenTimeout) & (ConnectionState != KnxConnectionState.disconnected)) { System.Threading.Thread.Sleep(100); i++; } // Den Heartbeat Timer stoppen //timerHeartbeat.Stop(); int Anz = (int)ar.AsyncState; IPEndPoint e = new IPEndPoint(IPAddress.Any, 0); try { udpClient.EndReceive(ar, ref e); udpClient.Close(); } catch (InvalidOperationException ex) { } timerHeartbeat.Stop(); } catch (Exception e) { Err("Close: " + e.ToString()); } return(ConnectionState == KnxConnectionState.disconnected); }
/// <summary> /// Daten auf den Bus senden /// </summary> /// <param name="emi">Telegrammdaten die gesendet werden sollen</param> public void Send(cEMI emi) { try { KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this); Tele.SetDataTelegramm(emi, SeqCounter++); byte[] TeleBytes = Tele.bytes; // KnxNetForm Debug("D>:" + KnxTools.BytesToString(TeleBytes)); udpClient.Send(TeleBytes, TeleBytes.Length); } catch (Exception e) { Err("Send: " + e.ToString()); } return; }
internal void DataAck(byte seqNo) { try { KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this); Tele.SetDataAckTelegramm(seqNo); byte[] TeleBytes = Tele.bytes; // KnxNetForm Debug("d>:" + KnxTools.BytesToString(TeleBytes)); udpClient.Send(TeleBytes, TeleBytes.Length); } catch (Exception e) { Err("DataAck: " + e.ToString()); } return; }
/// <summary> /// Öffnen der Verbindung /// </summary> /// <param name="gatewayIp"> IP Adresse des KnxIp-Gateways</param> /// <returns>Rückgabewert true bedeutet die Verbindung konnte geöffnet werden</returns> public bool Open(string gatewayIp) { this.gatewayIp = gatewayIp; //InitUdp(); try { udpClient.Connect(gatewayIp, gatewayPort); myIP = ((IPEndPoint)udpClient.Client.LocalEndPoint).Address; KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this); Tele.SetConnectTelegramm(); byte[] TeleBytes = Tele.bytes; //KnxNetForm.tb_Log.AppendText(Environment.NewLine + "O>:" + KnxTools.BytesToString(TeleBytes)); Debug("O>:" + KnxTools.BytesToString(TeleBytes)); udpClient.Send(TeleBytes, TeleBytes.Length); ConnectionState = KnxConnectionState.conReq; } catch (Exception e) { Err("Open: " + e.ToString()); } // nun den Listener starten ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), AnzTelegramme); // Warten auf Antwort, maximal OpenTimeout Sekunden int i = 0; while ((i < 10 * OpenTimeout) & (ConnectionState != KnxConnectionState.connected)) { System.Threading.Thread.Sleep(100); i++; } // Den Heartbeat Timer starten timerHeartbeat.Start(); return(ConnectionState == KnxConnectionState.connected); }
/// <summary> /// Diese Funktion wird vom UDP-Client aufgerufen wenn ein neues Telegramm eingetroffen ist /// </summary> /// <param name="ar"></param> public void ReceiveCallback(IAsyncResult ar) { int Anz = (int)ar.AsyncState; IPEndPoint e = new IPEndPoint(IPAddress.Any, 0); Byte[] receiveBytes = udpClient.EndReceive(ar, ref e); Anz++; Debug("Empf: Telegr[" + Anz + "]=" + KnxTools.BytesToString(receiveBytes)); int AnzBytes = receiveBytes.Length; if (AnzBytes < 7) { Err("Err: Telegramm zu kurz, wird verworfen. " + KnxTools.BytesToString(receiveBytes)); return; } try { // prüfen ob es ein ControlTelegramm ist if (receiveBytes[2] == 0x02) { // es ist ein Controlltelegramm switch (receiveBytes[3]) { case 0x01: // Search Request Debug("Search Request from Gateway"); Debug("<S:" + KnxTools.BytesToString(receiveBytes)); break; case 0x02: // Search Response _channelId = receiveBytes[6]; Debug("Search Response from Gateway"); Debug("<s:" + KnxTools.BytesToString(receiveBytes)); break; case 0x03: // Description Request Debug("Description Request from Gateway"); Debug("<D:" + KnxTools.BytesToString(receiveBytes)); break; case 0x04: // Description Response _channelId = receiveBytes[6]; Debug("Description Response from Gateway"); Debug("<d:" + KnxTools.BytesToString(receiveBytes)); break; case 0x05: // Connect Request Info("Connection Request from Gateway"); Debug("<O:" + KnxTools.BytesToString(receiveBytes)); break; case 0x06: // Connect Response _channelId = receiveBytes[6]; Info("ChannelId = " + _channelId); Debug("<o:" + KnxTools.BytesToString(receiveBytes)); if (receiveBytes[7] == 0) { ConnectionState = KnxConnectionState.connected; } break; case 0x07: // Heartbeat Request Debug("HeartbeatRequest for ChannelId = " + _channelId); Debug("<H:" + KnxTools.BytesToString(receiveBytes)); break; case 0x08: // Heartbeat Response Debug("HeartbeatResponse from ChannelId = " + _channelId); Debug("<h:" + KnxTools.BytesToString(receiveBytes)); if (receiveBytes[7] == 0) { ConnectionState = KnxConnectionState.connected; } break; case 0x09: // Disconnect Request Debug("DisconnectRequest for ChannelId = " + _channelId); Debug("<C:" + KnxTools.BytesToString(receiveBytes)); break; case 0x0A: // Disconnect Response Debug("Disconnected ChannelId = " + _channelId); Debug("<c:" + KnxTools.BytesToString(receiveBytes)); if (receiveBytes[7] == 0) { ConnectionState = KnxConnectionState.disconnected; } break; default: Debug("<?:" + KnxTools.BytesToString(receiveBytes)); break; } } else if (receiveBytes[2] == 0x04) { // es ist kein Controlltelegramm if (receiveBytes[3] == 0x20) { // es ist ein Datentelegramm // erst ein Ack senden DataAck(receiveBytes[8]); // Header entfernen int idx = 0x0A; int len = receiveBytes.Length - idx; byte[] t = new byte[len]; Array.Copy(receiveBytes, idx, t, 0, len); // und cemi Telegramm daraus erzeugen cEMI emi = new cEMI(t); Debug("ReceiveCallback: " + emi.ToString()); // Suchen des passenden HDKnx Objektes HDKnx hdKnx = HDKnxHandler.GetObject(emi); // und dort den Wert setzen, falls erforderlich hdKnx.SetValue(emi); // und auch das emi übergeben hdKnx.emi = emi; // Prüfen auf doppelte Telegramme if (hdKnx.Equals(last_hdKnx)) { // verwerfen //Info("doppeltes Telegramm verworfen:"); } else { //Console.WriteLine("Setze last Telegramm: \r\nvon {0} == \r\nzu {1}",last_hdKnx, hdKnx); last_hdKnx = new HDKnx(hdKnx.emi); // Rohdaten melden falls gewünscht if (rawTelegramReceived != null) { rawTelegramReceived(t); } // geänderte Daten melden falls gewünscht if (dataChanged != null) { Debug("KnxNet.ReceiveCallback vor dataChanged" + t.ToString()); dataChanged(hdKnx); Debug("KnxNet.ReceiveCallback nach dataChanged" + t.ToString()); } if (telegramReceived != null) { // Ein Delegate ist eingerichtet, dann diesen aufrufen telegramReceived(emi); } if (QueueEnable) { // in Queue speichern lock (fromKnxQueue) { fromKnxQueue.Enqueue(emi); } Debug("AddToQueue: " + emi.ToString()); } } } else if (receiveBytes[3] == 0x21) { // Bestätigung eines Datentelegramm Debug("Daten bestätigt status = " + receiveBytes[9]); } } ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), Anz); } catch (Exception ex) { Err("Err: Telegr[" + Anz + "]=" + KnxTools.BytesToString(receiveBytes)); Err("Err: ReceiveCallback: " + ex.ToString()); ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), Anz); } }