Files

181 lines
6.4 KiB
Python
Raw Permalink Normal View History

# from typing import Optional
# import struct
# from converter.base_converter import BaseConverter
# from utils.logger import logger
# from utils.checksum import calc_sum
# from utils.hex_helper import hex_dump
# from structure.b_frame import B_STAR_TIME_OFFSET, B_STAR_TIME_LEN
# from structure.d_frame import D_RAW_DATA_LEN
# from config.settings import FRAME_CONST
# class B2DConverter(BaseConverter):
# def convert(self, data: bytes) -> Optional[bytes]:
# try:
# # 1. 提取星上时
# star_time = data[B_STAR_TIME_OFFSET:B_STAR_TIME_OFFSET + B_STAR_TIME_LEN]
# if len(star_time) != 6:
# return None
# sec = star_time[:4]
# ms = star_time[4:]
# ms_4b = ms + b"\x00\x00"
# logger.info(f"星上时: {sec.hex()} {ms.hex()} → {ms_4b.hex()}")
# # 2. 拼装原始数据
# raw = sec + ms
# raw += b"\x00" * (D_RAW_DATA_LEN - len(raw))
# # 3. 校验域
# src = FRAME_CONST["SRC"]
# dst = FRAME_CONST["DST"]
# it = FRAME_CONST["IF_TYPE"]
# wa = FRAME_CONST["WORD_ADDR"]
# res2 = b"\x00\x00\x00\x00"
# check_data = struct.pack("BBBB", src, dst, it, wa) + res2 + raw
# cs = calc_sum(check_data)
# # 4. 组帧
# frame = (
# struct.pack(">H", FRAME_CONST["HEAD"])
# + struct.pack(">H", FRAME_CONST["SIM_ID"])
# + struct.pack(">H", 0x0000)
# + struct.pack(">H", FRAME_CONST["DATA_LEN"])
# + check_data
# + struct.pack(">H", cs)
# + struct.pack(">H", FRAME_CONST["TAIL"])
# )
# hex_dump(frame, "发送D帧")
# return frame
# except Exception as e:
# logger.error(f"B→D转换失败: {e}")
# return None
# @staticmethod
# def extract_bits(data: bytes, start_bit: int, bit_len: int) -> bytes:
# """
# 从字节流中精确提取 [start_bit, start_bit+bit_len) 比特
# 大端序、比特紧密对齐
# """
# bit_str = ''
# for byte in data:
# bit_str += f'{byte:08b}'
# end_bit = start_bit + bit_len
# selected = bit_str[start_bit:end_bit]
# # 不足补0
# if len(selected) < bit_len:
# selected += '0' * (bit_len - len(selected))
# # 转回 bytes
# res = b''
# for i in range(0, len(selected), 8):
# byte_bits = selected[i:i+8].ljust(8, '0')
# res += int(byte_bits, 2).to_bytes(1, byteorder='big')
# return res
from typing import Optional
import struct
from converter.base_converter import BaseConverter
from utils.logger import logger
from utils.checksum import calc_sum
from utils.hex_helper import hex_dump
from structure.d_frame import D_RAW_DATA_LEN
from config.settings import FRAME_CONST
class B2DConverter(BaseConverter):
def convert(self, data: bytes) -> Optional[bytes]:
try:
# ==============================================
# 【2026新版B遥测协议】星上时精确偏移
# ==============================================
START_BIT = 608 # 新版协议:星上时起始比特
STAR_TIME_BITS = 48 # 6B = 48b
# 从比特流中精确提取星上时
star_time_bytes = self.extract_bits(data, START_BIT, STAR_TIME_BITS)
if len(star_time_bytes) != 6:
logger.warning(f"星上时长度异常:{len(star_time_bytes)}B")
return None
# ==============================================
# 拆分4B秒 + 2B毫秒 → 毫秒扩展为4B
# ==============================================
seconds = star_time_bytes[:4]
ms = star_time_bytes[4:]
# ✅ 大端序:高位补 0x0000你要求的正确方式
ms_4b = b"\x00\x00" + ms
logger.info("✅ 星上时解析成功(新版协议)")
logger.info(f" 原始6B{star_time_bytes.hex()}")
logger.info(f" 秒值(4B){seconds.hex()}")
logger.info(f" 毫秒(2B→4B){ms.hex()}{ms_4b.hex()}")
# ==============================================
# 封装 D 软件帧
# ==============================================
#raw_data = seconds + ms
raw_data = seconds + ms_4b
raw_data += b"\x00" * (D_RAW_DATA_LEN - len(raw_data))
src = FRAME_CONST["SRC"]#源
dst = FRAME_CONST["DST"]#宿
if_type = FRAME_CONST["IF_TYPE"]#接口类型
word_addr = FRAME_CONST["WORD_ADDR"]#字地址
reserved2 = b"\x00\x00\x00\x00"#保留
check_data = (
struct.pack("BBBB", src, dst, if_type, word_addr)
+ reserved2
+ raw_data
)
checksum = calc_sum(check_data)
frame = (
struct.pack(">H", FRAME_CONST["HEAD"])
+ struct.pack(">H", FRAME_CONST["SIM_ID"])
+ struct.pack(">H", 0x0000)
+ struct.pack(">H", FRAME_CONST["DATA_LEN"])
+ check_data
+ struct.pack(">H", checksum)
+ struct.pack(">H", FRAME_CONST["TAIL"])
)
hex_dump(frame, "发送D软件完整帧")
return frame
except Exception as e:
logger.error(f"B→D转换失败{e}", exc_info=True)
return None
@staticmethod
def extract_bits(data: bytes, start_bit: int, bit_len: int) -> bytes:
"""
大端序比特紧密对齐
从data的 start_bit 位置提取 bit_len 长度比特 返回bytes
"""
# 把所有字节转成连续的01比特字符串
bitstream = ""
for byte in data:
bitstream += f"{byte:08b}"
# 截取需要的部分
selected_bits = bitstream[start_bit : start_bit + bit_len]
# 不足补0
if len(selected_bits) < bit_len:
selected_bits = selected_bits.ljust(bit_len, "0")
# 转回字节
result = b""
for i in range(0, len(selected_bits), 8):
segment = selected_bits[i:i+8].ljust(8, "0")
result += int(segment, 2).to_bytes(1, byteorder="big")
return result