/// <summary> /// Выполнить обработку поступившего пакета /// </summary> /// <param name="packet">Пакет, который необходимо обработать</param> protected void ParsePassive(Packet packet) { bool blocked = false; try { if (c_mutex.WaitOne(0, false)) { blocked = true; foreach (Parameter parameter in parameters) { int device = packet.Com_Packet[1] & 0x7F; bool isFromDevice = ((packet.Com_Packet[1] & 0x80) > 0) ? true : false; if (isFromDevice) { if (device == parameter.Device) { float value = float.NaN; value = GetFromDsn(packet.Com_Packet, parameter.Device, parameter.Offset, parameter.Size, parameter.IsLittleEndian); SaveValue(parameter.Position, value); } } } } } finally { if (blocked) c_mutex.ReleaseMutex(); } }
/// <summary> /// Добавить пакет в статический список /// </summary> /// <param name="packet">Добавляемый пакет</param> public void InsertPacketToStatic(Packet packet) { bool blocked = false; try { if (s_mutex.WaitOne(100, false)) { blocked = true; packet.Role = Role.Master; packet.Content = Content.Sensor; static_list.Add(packet); } } finally { if (blocked) s_mutex.ReleaseMutex(); } }
private void Add_Click(object sender, EventArgs e) { InsertCommand ins = new InsertCommand(); ins.typeCRC = typeCRC; ins.Text = "Добавление новой команды опроса"; if (ins.ShowDialog(this) == DialogResult.OK) { Packet p = new Packet(); p.Com_Packet = ins.ComPacket; p.IsActived = ins.Actived; p.PortType = ins.TypePort; p.Interval = ins.Interval; packets.Add(p); InsertCommand(ins.Commanda, ins.Actived, string.Empty, p); } }
/// <summary> /// Выполнить обработку поступившего пакета /// </summary> /// <param name="packet">Пакет, который необходимо обработать</param> protected void Parse(Packet packet) { bool blocked = false; try { if (c_mutex.WaitOne(0, false)) { blocked = true; if (packet.Role == Role.Slave && packet.Content == Content.Sensor) { foreach (Parameter parameter in parameters) { int device = packet.Com_Packet[1] & 0x7F; if (device == parameter.Device) { float value = float.NaN; value = GetFromDsn(packet.Com_Packet, parameter.Device, parameter.Offset, parameter.Size, parameter.IsLittleEndian); SaveValue(parameter.Position, value); } } } } } catch (Exception ex) { if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "Stock -> Parse", ErrorType.NotFatal)); } } finally { if (blocked) c_mutex.ReleaseMutex(); } }
private void InsertCommand(string command, bool actived, string namecmd, Packet pack) { ListViewItem item = new ListViewItem(); item.Checked = actived; ListViewItem.ListViewSubItem fl = new ListViewItem.ListViewSubItem(item, command.Substring(0, 2)); ListViewItem.ListViewSubItem ladd = new ListViewItem.ListViewSubItem(item, command.Substring(2, 2)); ListViewItem.ListViewSubItem lpak = new ListViewItem.ListViewSubItem(item, command.Substring(4, 2)); ListViewItem.ListViewSubItem cmd = new ListViewItem.ListViewSubItem(item, command.Substring(6, 2)); ListViewItem.ListViewSubItem adr = new ListViewItem.ListViewSubItem(item, command.Substring(8, 2)); ListViewItem.ListViewSubItem ldata = new ListViewItem.ListViewSubItem(item, command.Substring(10, 2)); ListViewItem.ListViewSubItem data = new ListViewItem.ListViewSubItem(item, string.Empty); ListViewItem.ListViewSubItem status = new ListViewItem.ListViewSubItem(item, command.Substring(12, 2)); ListViewItem.ListViewSubItem crc = new ListViewItem.ListViewSubItem(item, command.Substring(14, 2)); string port_name = string.Empty; if (pack.PortType == TypePort.Primary) { port_name = "Основной"; } else if (pack.PortType == TypePort.Secondary) { port_name = "Вспомогательный"; } else { port_name = "Порт не определен"; } ListViewItem.ListViewSubItem name = new ListViewItem.ListViewSubItem(item, port_name); ListViewItem.ListViewSubItem inter = new ListViewItem.ListViewSubItem(item, pack.Interval.TotalMilliseconds.ToString()); item.SubItems.Add(fl); item.SubItems.Add(ladd); item.SubItems.Add(lpak); item.SubItems.Add(cmd); item.SubItems.Add(adr); item.SubItems.Add(ldata); item.SubItems.Add(data); item.SubItems.Add(status); item.SubItems.Add(crc); item.SubItems.Add(name); item.SubItems.Add(inter); listView1.Items.Add(item); item.Tag = pack; if (actived) item.Checked = true; }
/// <summary> /// Поступили данные по TCP /// </summary> /// <param name="packet">поступивший по Tcp пакет</param> private void devTcpOld_OnPacket(string packet) { try { Packet pack = new Packet(); pack.Com_Packet = PacketTranslater.TranslateToUnigueFormatTcpPacket(packet, crc); pack.Tcp_Packet = PacketTranslater.FromUnigueToTcp(pack.Com_Packet); pack.Wait = false; if (protocol.IsToDevice(pack.Tcp_Packet)) { if (protocol.IsRead(pack.Tcp_Packet)) { pack.Wait = true; } } else { pack.Role = Role.Slave; DisplayPacket[] packs = Display.Packets; if (packs != null) { foreach (DisplayPacket _pack in packs) { int device = pack.Com_Packet[1] & 0x1F; if (device == _pack.Device) { pack.PortType = _pack.TypePort; break; } } } } devTcpOld.Place.Insert(pack); } catch (Exception ex) { journal.Write(ex.Message + "Application -> devTcpOld_OnPacket", EventLogEntryType.Error); } }
/// <summary> /// Удалить пакет из репозитария /// </summary> /// <param name="packet">Удаляемый пакет</param> public void Remove(Packet packet) { if (mutex.TryEnterWriteLock(500)) { try { packets.Remove(packet); } catch (Exception ex) { throw new Exception(ex.Message, ex); } finally { mutex.ExitWriteLock(); } } }
/// <summary> /// Осуществляет разбор байтов на осмысленные пакеты /// </summary> private void TranslaterFunction() { bool blocked = false; try { if (passive_mutex.WaitOne(100, false)) { blocked = true; while (output.Count > 0) { byte item = output[0]; switch (item) { case start_byte: if (output.Count < (l_pak + 1)) { return; } int size_of_packet = output[l_pak] + 1; if (size_of_packet >= packet_min_size && size_of_packet <= packet_max_size) { if (output.Count < size_of_packet) { return; } if (calculator.Calculate(0, size_of_packet, output.ToArray())) { byte[] packet = new byte[size_of_packet]; output.CopyTo(0, packet, 0, size_of_packet); output.RemoveRange(0, size_of_packet); Packet pack = new Packet(); pack.Role = Role.Default; pack.Content = Content.Default; pack.Source = PacketSource.Default; pack.Com_Packet = packet; if (OnPacket != null) { OnPacket(this, new SerialEventArgs(pack)); } } else { output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); } } else { output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); } break; default: output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); break; } } } } catch (Exception ex) { if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "Serial -> TranslaterFunction", ErrorType.NotFatal)); } } finally { if (blocked) { passive_mutex.ReleaseMutex(); } } }
/// <summary> /// Ожидать ответ /// </summary> /// <param name="item">Отправленный пакет</param> private void WaitAnswer(Packet item) { try { answerWaiter.Reset(); if (answerWaiter.WaitOne(answerTimeout, false)) // ожидаем ответ от устройства { // получен ответ от устройства if (response != null) { Interlocked.Increment(ref c_received_packets); Interlocked.Add(ref c_received_bytes, response.Length); if (OnPacket != null) { Packet packet = new Packet(); packet.Com_Packet = response; packet.Role = Role.Slave; packet.Content = item.Content; OnPacket(this, new SerialEventArgs(packet)); } } } else { // ответ от устройства не получен Interlocked.Increment(ref c_lost_packets); // количество не ответов } } catch (Exception ex) { // ... не смогли считать данные из порта ... response = null; if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "Serial -> WaitAnswer", ErrorType.NotFatal)); } } }
/// <summary> /// Метод, выполняющий обработку при получении данных из порта /// </summary> /// <param name="sender">Источник события</param> /// <param name="e">Передаваемы данные</param> private void DataReceived(object sender, SerialDataReceivedEventArgs e) { try { switch (e.EventType) { case SerialData.Chars: if (app.Mode == ApplicationMode.Passive) { byte[] resp = new byte[port.BytesToRead]; int readed = port.Read(resp, 0, resp.Length); if (state == State.Running) { PassiveWork(resp); } port.DiscardInBuffer(); port.DiscardOutBuffer(); } else { response = GetResponse(); if (answerWaiter.WaitOne(0, false)) { if (response != null) { Interlocked.Increment(ref c_received_packets); Interlocked.Add(ref c_received_bytes, response.Length); if (OnPacket != null) { Packet packet = new Packet(); packet.Com_Packet = response; packet.Role = Role.Slave; packet.Content = Content.Unknown; OnPacket(this, new SerialEventArgs(packet)); } } } else answerWaiter.Set(); } break; case SerialData.Eof: break; default: break; } } catch (Exception ex) { if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "Serial -> DataReceived", ErrorType.NotFatal)); } } }
/// <summary> /// Проверить нужли данный пакет отправлять в порт /// </summary> /// <param name="packet">Проверяемый пакет</param> /// <returns>true - если данный пакет нужно отправить в порт, false - если не нужно отправлять пакет в порт</returns> protected bool IsNeedToPort(Packet packet) { if (packet.Sended == false) { if (packet.PortType == t_port) { if (packet.Role == Role.Slave) { return true; } } if (s_list.Length > 0) { foreach (Packet p in s_list) { if (p.PortType == t_port) { if (p.Com_Packet[1] == packet.Com_Packet[1]) { return true; } } } } else return true; } return false; }
protected Packet packet = null; // передаваемый пакет #endregion Fields #region Constructors /// <summary> /// инициализирует новый экземпляр класса /// </summary> /// <param name="pack">Пакет, для передачи</param> public SerialEventArgs(Packet pack) { packet = pack; }
/// <summary> /// Удалить пакет из статического списка /// </summary> /// <param name="packet">Удаляемый пакет</param> public void RemovePacketFromStatic(Packet packet) { bool blocked = false; try { if (s_mutex.WaitOne(100, false)) { blocked = true; static_list.Remove(packet); } } finally { if (blocked) s_mutex.ReleaseMutex(); } }
/// <summary> /// Загрузить команду опроса /// </summary> /// <param name="root">Узел в котором находятся параметры для загрузки</param> protected void LoadPacket(XmlNode root) { if (root != null) { if (root.Name == staticCommandaName) { XmlNodeList childs = root.ChildNodes; if (childs != null) { Packet packet = new Packet(); foreach (XmlNode child in childs) { switch (child.Name) { case com_packetName: packet.Com_Packet = GetComByte(child.InnerText); break; case tcp_packetName: packet.Tcp_Packet = child.InnerText; break; case waitName: try { packet.Wait = Boolean.Parse(child.InnerText); } catch { packet.Wait = true; } break; case activedName: try { packet.IsActived = Boolean.Parse(child.InnerText); } catch { packet.IsActived = true; } break; case contentName: try { packet.Content = (Content)Enum.Parse(typeof(Content), child.InnerText); } catch { packet.Content = Content.Default; } break; case roleName: try { packet.Role = (Role)Enum.Parse(typeof(Role), child.InnerText); } catch { packet.Role = Role.Master; } break; case packetSourceName: try { packet.Source = (PacketSource)Enum.Parse(typeof(PacketSource), child.InnerText); } catch { packet.Source = PacketSource.Static; } break; case "port_type": try { packet.PortType = (TypePort)Enum.Parse(typeof(TypePort), child.InnerText); } catch { } break; case "interval": try { packet.Interval = TimeSpan.Parse(child.InnerText); } catch { } break; } } InsertPacketToStatic(packet); } } } }
/// <summary> /// Инициирует процедуру отправки пакетов на блоки отображения /// </summary> /// <param name="state">Не используется</param> private void TimerCallback(object state) { bool blocked = false; try { if (t_mutex.WaitOne(0, false)) { blocked = true; if (Interlocked.Read(ref counter) > 0) { Interlocked.Exchange(ref counter, 0); DateTime now = DateTime.Now; // текущее время // ... if (app != null) { Float[] result = app.Converter.GetResults(); if (result != null) { DisplayPacket[] packs = Packets; foreach (var packet in packs) { TimeSpan elapsed = now - packet.LastTime; if (elapsed >= packet.Period) { packet.LastTime = now; byte[] com = GetComPacket(packet, result); if (com != null) { Packet pack = new Packet(); pack.ToPort = packet.ToPort; pack.IsActived = packet.IsActived; pack.Role = Role.Slave; pack.Content = Content.Unknown; pack.Wait = false; pack.Com_Packet = com; pack.PortType = packet.TypePort; packet.Place.Clear(); packet.Place.Insert(pack); } } } if (OnComplete != null) { OnComplete(this, null); } } } } else return; } } catch (Exception ex) { if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "DisplayUnit ->TimerCallback", ErrorType.NotFatal)); } } finally { if (blocked) t_mutex.ReleaseMutex(); } }
/// <summary> /// Обработать пакет /// </summary> /// <param name="packet">Пакет для обработки</param> private void Write(Packet packet) { try { port.DiscardInBuffer(); // выполняем очистку port.DiscardOutBuffer(); // входного и выходного буфера port.Write(packet.Com_Packet, 0, packet.Com_Packet.Length); // записываем пакет в порт if (OnPacket != null) OnPacket(this, new SerialEventArgs(packet)); // передаем пакет наружу Interlocked.Increment(ref c_send_packets); // увеличиваем соответствующие Interlocked.Add(ref c_send_bytes, packet.Com_Packet.Length); // счетчики if (packet.Wait) WaitAnswer(packet); // если необходимо, ожидаем ответ на пакет if (WaitTimeout >= 10) { Thread.Sleep(WaitTimeout); } } catch { // ... предпологается что не смогли записать в порт пакет ... if (OnPortFail != null) { OnPortFail(this, new EventArgs()); } return; } }
/// <summary> /// Осуществляет разбор байтов на осмысленные пакеты /// </summary> private void TranslaterFunction() { bool blocked = false; try { if (passive_mutex.WaitOne(100, false)) { blocked = true; while (output.Count > 0) { byte item = output[0]; switch (item) { case start_byte: if (output.Count < (l_pak + 1)) return; int size_of_packet = output[l_pak] + 1; if (size_of_packet >= packet_min_size && size_of_packet <= packet_max_size) { if (output.Count < size_of_packet) return; if (calculator.Calculate(0, size_of_packet, output.ToArray())) { byte[] packet = new byte[size_of_packet]; output.CopyTo(0, packet, 0, size_of_packet); output.RemoveRange(0, size_of_packet); Packet pack = new Packet(); pack.Role = Role.Default; pack.Content = Content.Default; pack.Source = PacketSource.Default; pack.Com_Packet = packet; if (OnPacket != null) { OnPacket(this, new SerialEventArgs(pack)); } } else { output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); } } else { output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); } break; default: output.RemoveAt(0); Interlocked.Increment(ref c_lost_bytes); break; } } } } catch (Exception ex) { if (OnError != null) { OnError(this, new ErrorArgs(ex.Message + "Serial -> TranslaterFunction", ErrorType.NotFatal)); } } finally { if (blocked) passive_mutex.ReleaseMutex(); } }
/// <summary> /// Отправить пакет в порт /// </summary> /// <param name="packet">Пакет для отправки в COM порт. Версия TCP протокола обмена</param> public void ToCOM(string packet) { try { Packet pack = new Packet(); pack.Com_Packet = PacketTranslater.TranslateToUnigueFormatTcpPacket(packet, app.TypeCRC); pack.Tcp_Packet = PacketTranslater.FromUnigueToTcp(pack.Com_Packet); pack.Wait = false; if (app.IProtocol.IsToDevice(pack.Tcp_Packet)) { if (app.IProtocol.IsRead(pack.Tcp_Packet)) { pack.Wait = true; } } place.Insert(pack); } catch { } }