JT808 icon indicating copy to clipboard operation
JT808 copied to clipboard

0704构包,无法解析,是否缺少必要字段?

Open draco-wang opened this issue 7 months ago • 4 comments

public static byte[] BuildBatchLocationReportMessage(List<State> states, Vehicle vehicle, ushort msgNum, DateTime GpsTime) { if (states == null || states.Count == 0) throw new ArgumentException("状态列表为空", nameof(states));

if (vehicle == null)
    throw new ArgumentNullException(nameof(vehicle));

var jt808_0200s = new List<JT808_0x0200>();
var currentGpsTime = GpsTime;

foreach (var state in states)
{
    var jT808_0x0200 = new JT808_0x0200
    {
        Lat = (int)(state.Latitude * 1_000_000),
        Lng = (int)(state.Longitude * 1_000_000),
        GPSTime = currentGpsTime,
        StatusFlag = (uint)(JT808Status.acc_open | JT808Status.location | JT808Status.used_gps),
        AlarmFlag = 0,
        Altitude = 0,
        Speed = (ushort)(state.Speed * 10),
        Direction = (ushort)state.Direction,


        BasicLocationAttachData = new Dictionary<byte, JT808_0x0200_BodyBase>
        {
            { 0x01, new JT808_0x0200_0x01 { Mileage = 0 } } // 这里先传0
        }
    };

    jt808_0200s.Add(jT808_0x0200);
    currentGpsTime = currentGpsTime.AddMilliseconds(vehicle.IntervalMilliseconds * 1000);
}

if (jt808_0200s.Count == 0)
{
    Log.Warning("[BuildBatchLocationReportMessage] 所有状态数据无效,无法生成批量位置上报消息");
    return Array.Empty<byte>();
}

var batchReport = new JT808_0x0704
{
    LocationType = BatchLocationType.正常位置批量汇报,
    Count = (ushort)jt808_0200s.Count,
    Positions = jt808_0200s
};

var package = new JT808Package
{
    Header = new JT808Header
    {
        MsgId = (ushort)JT808MsgId._0x0704,
        MsgNum = msgNum,
        TerminalPhoneNo = vehicle.TerminalPhoneNo
    },
    Bodies = batchReport,
    Version = vehicle.Version
};

if (vehicle.Version == JT808Version.JTT2019)
{
    package.Header.ProtocolVersion = 1;
}

try
{
    lock (JT808Serializer)
    {
        byte[] serializedData = JT808Serializer.Serialize(package, vehicle.Version);
        Log.Information($"成功序列化数据包,数据大小: {serializedData.Length}字节");
        return serializedData;
    }
}
catch (IndexOutOfRangeException ex)
{
    Log.Error($"[BuildBatchLocationReportMessage] 索引越界异常:{ex.Message}\n" +
              $"状态数据数量: {jt808_0200s.Count}, vehicleId: {vehicle.VehicleId}, version: {vehicle.Version}");
}
catch (Exception ex)
{
    Log.Error($"[BuildBatchLocationReportMessage] 序列化失败:{ex.Message}");
}

return Array.Empty<byte>();

}

draco-wang avatar Apr 23 '25 10:04 draco-wang

提供组包后的hex数据看下。

SmallChi avatar Apr 24 '25 02:04 SmallChi

已解决消息体过长被服务端抛弃,建议抛出异常

draco-wang avatar Apr 24 '25 09:04 draco-wang

2025-05-27 16:14:14 >> 7E070401111989031088810003000900001C00000000000400030261525406F102E00000003A005B250501000000001C00000000000400030261525406F102FC0000002B005B250501000002001C00000000000400030261525306F1031F00000035005B250501000004001C00000000000400030261525206F1034400000039005B250501000006001C00000000000400030261525206F1036A0000003A005B250501000008001C00000000000400030261525106F1038500000029005B250501000010001C00000000000400030261525106F103A700000032005B250501000012001C00000000000400030261525006F103C100000039005B250501000014001C00000000000400030261525006F103C100000000005B250501000016667E 0704又测试一次,失败

draco-wang avatar May 27 '25 08:05 draco-wang

    public static byte[] BuildBatchLocationReportMessage(List<State> states, Vehicle vehicle, ushort msgNum, DateTime GpsTime)
    {
        if (states == null || states.Count == 0)
            throw new ArgumentException("状态列表为空", nameof(states));

        if (vehicle == null)
            throw new ArgumentNullException(nameof(vehicle));

        var jt808_0200s = new List<JT808_0x0200>();
        var currentGpsTime = GpsTime;

        foreach (var state in states)
        {
            var jT808_0x0200 = new JT808_0x0200
            {
                Lat = (int)(state.Latitude * 1_000_000),
                Lng = (int)(state.Longitude * 1_000_000),
                GPSTime = currentGpsTime,
                StatusFlag = (uint)(JT808Status.acc_open | JT808Status.location | JT808Status.used_gps),
                AlarmFlag = 0,
                Altitude = 0,
                Speed = (ushort)(state.Speed * 10),
                Direction = (ushort)state.Direction,
            };

            jt808_0200s.Add(jT808_0x0200);
            currentGpsTime = currentGpsTime.AddMilliseconds(vehicle.IntervalMilliseconds * 1000);
        }

        if (jt808_0200s.Count == 0)
        {
            Log.Warning("[BuildBatchLocationReportMessage] 所有状态数据无效,无法生成批量位置上报消息");
            return Array.Empty<byte>();
        }

        var batchReport = new JT808_0x0704
        {
            LocationType = BatchLocationType.正常位置批量汇报,
            Count = (ushort)jt808_0200s.Count,
            Positions = jt808_0200s
        };

        var package = new JT808Package
        {
            Header = new JT808Header
            {
                MsgId = (ushort)JT808MsgId._0x0704,
                MsgNum = msgNum,
                TerminalPhoneNo = vehicle.TerminalPhoneNo
            },
            Bodies = batchReport,
            Version = vehicle.Version
        };

        if (vehicle.Version == JT808Version.JTT2019)
        {
            package.Header.ProtocolVersion = 1;
        }
        try
        {
            lock (JT808Serializer)
            {
                byte[] serializedData = JT808Serializer.Serialize(package, vehicle.Version);

                // 将字节数组转换为十六进制字符串
                string hexString = BitConverter.ToString(serializedData).Replace("-", " ");
                Console.WriteLine("序列化的值:");
                Console.WriteLine(hexString);
                return serializedData;
            }
        }
        catch (IndexOutOfRangeException ex)
        {
            Log.Error($"[BuildBatchLocationReportMessage] 索引越界异常:{ex.Message}\n" +
                      $"状态数据数量: {jt808_0200s.Count}, vehicleId: {vehicle.VehicleId}, version: {vehicle.Version}");
        }
        catch (Exception ex)
        {
            Log.Error($"[BuildBatchLocationReportMessage] 序列化失败:{ex.Message}");
        }

        return Array.Empty<byte>();
    }这个是构包的方法

draco-wang avatar May 27 '25 08:05 draco-wang