Нахождение телеграмм MBUS в байте [] - PullRequest
2 голосов
/ 18 августа 2011

Я пытаюсь прочитать MBUS телеграммы с последовательного порта.Я помещаю все из последовательного порта в массив байтов.

Каждая телеграмма MBUS начинается с этого шаблона (в шестнадцатеричном формате): 68 XX XX 68
где XX - длина телеграммы в байтах.

Пример: Пример http://img97.imageshack.us/img97/6004/mbustele.jpg

Здесь вы видите пример, выделено начало телеграммы длиной 99 (в шестнадцатеричном формате)

Я хочу добавить каждую телеграмму в списоквот так

List<byte[]> telegramms;

Идея как этого добиться?

Ответы [ 2 ]

1 голос
/ 18 августа 2011

Я только что напечатал это в VisualStudio 2010, он делает всевозможные предположения о порядке байтов и не решает потенциальную проблему, связанную с размером пакета MBus, превышающим размер выборочного байта от последовательного порта, или, что более важно, , если сам пакет header находится за границей между пакетами из последовательного порта.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace StackOverflowTest
{
    [TestClass]
    public class ByteTest
    {
        private bool FindEndMark(byte[] source, int index, out int size)
        {
            int endIndex = index + 3;
            if (endIndex > source.Count())
            {
                // need to cope with the fact that the datapacket might be shorter than the MBus message.
                throw new Exception("end count > length of array");
            }

        if (source[endIndex] == 0x68)
        {
            // According to the updated spec, the size is emitted twice as a verification
            if (source[index + 1] == source[index + 2])
            {
                size = source[index] + 1;
                return true;
            }
        }
            size = 0;
            return false;
        }

        [TestMethod]
        public void FindMbusDatagram()
        {
            byte[] src = new byte[]
                {
                    // Random junk to start
                    00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0xa, 0xb, 0xc, 0xd, 
                    // An MBus Packet
                    0x68, 06, 00, 0x68, 08, 05, 72, 00, 00, 00, 
                    // More junk
                    00, 00, 00, 0x16, 00, 00, 00, 00, 01, 
                    // Put a rogue 0x68 in so we can prove we don't get false positives in the datastream
                    0x68, 03, 04, 05, 06, 07, 08, 09, 0xa, 0xb, 0xc, 0xd,
                    // Another Packet
                    0x68, 01, 00, 0x68, 0xFF,
                    //final junk
                     00, 16, 00, 00, 00, 01, 02, 03
                };

            List<byte[]> packets = new List<byte[]>();

            for (int i = 0; i < src.Length; i++ )
            {
                if (src[i] != 0x68)
                {
                    continue;
                }
                else
                {
                    int packetSize = 0;
                    if (FindEndMark(src, i, out packetSize))
                    {
                        if (packetSize > (src.Length - i))
                        {
                            // read more data from your port and append it somehow.
                        }
                        else
                        {
                            // We're packetSize+4 includes the header information + checksum and end
                        // NB: packetSize+5 is a checksum byte
                        // NB: packetSize+6 should be 0x16 according to the MBus spec.
                            byte[] packet = new byte[packetSize + 4];
                            int count = 0;

                            // Copy the packet + header into a byte[]
                            for (int j = i; j < (i + packetSize + 4); j++)
                            {
                                packet[count++] = src[j];
                            }

                            packets.Add(packet);

                            // Move the counter along
                            i += (packetSize + 4);
                        }
                    }
                }
            }

            // Should have two packets here.
            Assert.IsTrue(packets.Count > 0);
        }
    }
}
0 голосов
/ 19 августа 2011

Вот моя попытка, что вы думаете?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MBUS_Parse_Test.MDL64_Communication
{
    /// <summary>
    /// Extracts MBUS telegramms
    /// </summary>
    class GetMBUS_Telegramms
    {
    #region Eigenschaften
    private static List<MbusTelegram> telegrams = new List<MbusTelegram>();
    #endregion

    public static List<MbusTelegram> GetTelegramms(byte[] logfile)
    {
        int startOfTele = ExtractFirstMBUSTelegramm(logfile);
        while (startOfTele != 0)
        {
            byte[] NewLogFile = new byte[logfile.Length - startOfTele];
            Buffer.BlockCopy(logfile, startOfTele, NewLogFile, 0, NewLogFile.Length);
            startOfTele = ExtractFirstMBUSTelegramm(NewLogFile);
            logfile = NewLogFile;
        }
        return telegrams;
    }

    private static int ExtractFirstMBUSTelegramm(byte[] logfile)
    {
        byte mbus_start = 0x68;
        int Start = Array.IndexOf(logfile, mbus_start);
        int offset = 10;
        if (logfile[Start + 3] == mbus_start)
        {
            byte[] newMBUS = new byte[logfile[Start + 1] + offset];
            Buffer.BlockCopy(logfile, Start, newMBUS, 0, logfile[Start + 1] + offset);
            MbusTelegram nuMBUS = new MbusTelegram(newMBUS);
            telegrams.Add(nuMBUS);
            return (Start + logfile[Start + 1] + offset);
        }
        return 0;
    }

    private System.Array ResizeArray(System.Array oldArray, int newSize)
    {
        int oldSize = oldArray.Length;
        System.Type elementType = oldArray.GetType().GetElementType();
        System.Array newArray = System.Array.CreateInstance(elementType, newSize);
        int preserveLength = System.Math.Min(oldSize, newSize);
        if (preserveLength > 0)
            System.Array.Copy(oldArray, newArray, preserveLength);
        return newArray;
    }
  }
}
...