1.心跳刷新时机更改成接收到任意数据时刷新
2.拆分工控机收发线程和业务处理线程
3.优化拆包解析PB
4.心跳刷新机制更改,使用telematic发送时间做校验,加入可配置超时时间方法以及是否启用超时检测方法
This commit is contained in:
xinfengkun
2022-05-17 19:05:08 +08:00
parent 7c01c637e4
commit 0ab8f2621f
36 changed files with 888 additions and 810 deletions

View File

@@ -1,6 +1,6 @@
package com.zhidao.adas.client.bean;
import com.zhidao.support.adas.high.common.DigitalTrans;
import com.zhidao.support.adas.high.common.ByteUtil;
import com.zhidao.support.adas.high.common.ProtocolStatus;
public class ErrorData extends BaseInfo {
@@ -15,6 +15,6 @@ public class ErrorData extends BaseInfo {
@Override
public String toString() {
return status + "\n原始数据" + DigitalTrans.byte2HexStr(bytes);
return status + "\n原始数据" + ByteUtil.byteArrToHex(bytes);
}
}

View File

@@ -78,15 +78,19 @@ import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.protocol.RawData;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import chassis.VehicleStateOuterClass;
import io.netty.channel.Channel;
@@ -249,7 +253,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
connect.setVisibility(View.GONE);
disconnect.setVisibility(View.GONE);
cb_timeout.setVisibility(View.GONE);
ReceiveTimeoutManager.getInstance().setEnable(false, AdasManager.getInstance().getIpcConnectionStatus());
AdasManager.getInstance().setEnableTimeoutDetection(false);
}
role.setOnClickListener(new View.OnClickListener() {
@Override
@@ -343,19 +347,46 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
});
boolean isEnable = Constants.getTimeoutEnable(this);
ReceiveTimeoutManager.getInstance().setEnable(isEnable, AdasManager.getInstance().getIpcConnectionStatus());
AdasManager.getInstance().setEnableTimeoutDetection(isEnable);
cb_timeout.setChecked(ReceiveTimeoutManager.getInstance().isEnable());
cb_timeout.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Constants.setTimeoutEnable(MainActivity.this, isChecked);
ReceiveTimeoutManager.getInstance().setEnable(isChecked, AdasManager.getInstance().getIpcConnectionStatus());
AdasManager.getInstance().setEnableTimeoutDetection(isChecked);
}
});
cb_timeout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
showToastCenter("由于没有心跳机制,如果服务器端断网或其他非正常断开,客户端无法感知,所以需要进行数据接收超时检测", Toast.LENGTH_LONG);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("超时时间配置");
View view = getLayoutInflater().inflate(R.layout.dialog_timeout, null);
final EditText et = view.findViewById(R.id.et);
String timeout = String.valueOf(AdasManager.getInstance().getTimeoutDetectionTime());
et.setText(timeout);
et.setSelection(timeout.length());
final TextView hint = view.findViewById(R.id.text_hint);
hint.setText("由于没有心跳机制,如果服务器端断网或其他非正常断开,客户端无法感知,所以需要进行数据接收超时检测");
builder.setView(view);//
builder.setCancelable(false);//
builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Editable editable = et.getText();
if (TextUtils.isEmpty(editable)) {
// 条件不成立不能关闭 AlertDialog 窗口
Toast.makeText(MainActivity.this, "请输入超时时间", Toast.LENGTH_SHORT).show();
return;
}
String temp = et.getText().toString().trim();
long t = Long.parseLong(temp);
AdasManager.getInstance().setTimeoutDetectionTime(t);
}
});
//设置反面按钮,并做事件处理
builder.setNegativeButton("取消", null);
builder.show();//显示Dialog对话框
return true;
}
});
@@ -585,7 +616,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
break;
case Constants.TITLE.RECEIVE_TRACKED_OBJECTS:
hintTrackedObjects(false);
// hintTrackedObjects(false);
if (viewFragment == null)
viewFragment = new InfoFragment(data);
if (!viewFragment.isVisible()) {
@@ -675,7 +706,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
break;
case Constants.TITLE.RECEIVE_PERCEPTION_OBSTACLES:
hintTrackedObjects(true);
// hintTrackedObjects(true);
if (perceptionObstaclesFragment == null)
perceptionObstaclesFragment = new InfoFragment(data);
if (!perceptionObstaclesFragment.isVisible()) {
@@ -783,6 +814,20 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
return status;
}
//计算耗时
// AtomicInteger integer = new AtomicInteger(0);
// AtomicLong atomicLong = new AtomicLong(0);
// AtomicLong timeLong = new AtomicLong(0);
//
// private void calculateTimeConsuming(RawData raw) {
// int num = integer.incrementAndGet();
// long time = timeLong.addAndGet(System.nanoTime() - raw.receiveTime);
// long size = atomicLong.addAndGet(raw.originalData.size());
// if (num % 1000 == 0) {
// double m = time / 1000000.0 / num;
// Log.i("优化后", num + "条数据,平均解析速度=" + m + "毫秒,共接收=" + size + "字节");
// }
// }
@Override
public void onError(ProtocolStatus status, byte[] bytes) {
@@ -850,6 +895,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
DataDistribution.getInstance().addData(base);
// String data = PointCloudDecoder.decode(header, pointCloud);
// Log.i("dddd", "data==" + data.length());
// Log.i("dddd", "data==" + data);
// LogSave.getInstance().saveLog("转换数据=" + data);
}
@@ -909,7 +955,8 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onMessageResponseClient(MogoProtocolMsg msg, String sign, Channel channel) {
AdasManager.getInstance().parseIPCData(msg.getBody());
Log.i("ddd", "dddd" + sign);
AdasManager.getInstance().decoderRaw(msg.getBody());
}
@Override
@@ -979,7 +1026,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
if (NSDNettyManager.getInstance().isServerStart()) {
NSDNettyManager.getInstance().sendMsgToAllClients(new MogoProtocolMsg(NORMAL_DATA, bytes.length, bytes));
} else {
Log.d("dddd", "司机端Server未启动");
// Log.d("dddd", "司机端Server未启动");
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<EditText
android:id="@+id/et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:digits="0123456789"
android:gravity="center"
android:hint="毫秒值(>=1000)"
android:imeOptions="flagNoExtractUi"
android:inputType="number"
android:maxLength="10"
android:maxLines="1"
android:minWidth="100dp"
android:textColor="#000"
android:textSize="16sp" />
<TextView
android:id="@+id/text_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textColor="#000"
android:textSize="16sp" />
</LinearLayout>

View File

@@ -475,7 +475,7 @@ class MoGoAutopilotProvider :
try {
msg?.let {
when (it.protocolType) {
NORMAL_DATA -> AdasManager.getInstance().parseIPCData(it.body)
NORMAL_DATA -> AdasManager.getInstance().decoderRaw(it.body)
SYNC_MODE_STATUS -> {
FunctionBuildConfig.isDemoMode = when (it.body[0].toInt()) {
1 -> true

View File

@@ -5,7 +5,6 @@ import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_ALIAS_CODE_ADAS
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_ALIAS_CODE_CONNECT_ADDRESS;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_ALIAS_CODE_INIT;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_ALIAS_CODE_STATUS_CHANGE_REASON;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_BYTE;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_LINK_ADAS;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_LINK_LOG_CONNECT_STATUS;
import static com.zhidao.support.adas.high.chain.AdasChain.CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT;
@@ -18,15 +17,17 @@ import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.TextFormat;
import com.zhidao.support.adas.high.bean.BaseInfo;
import com.zhidao.support.adas.high.bean.VersionCompatibility;
import com.zhidao.support.adas.high.common.ByteUtil;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.Define;
import com.zhidao.support.adas.high.common.DigitalTrans;
import com.zhidao.support.adas.high.common.IPCFixationIPHelper;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.common.RegexUtils;
import com.zhidao.support.adas.high.msg.IMsg;
import com.zhidao.support.adas.high.msg.MyMessageFactory;
@@ -36,6 +37,7 @@ import com.zhidao.support.adas.high.protocol.RawUnpack;
import com.zhidao.support.adas.high.queue.WSByteQueueManager;
import com.zhidao.support.adas.high.queue.WebSocketQueueManager;
import com.zhidao.support.adas.high.socket.FpgaSocket;
import com.zhidao.support.adas.high.thread.DispatchHandler;
import com.zhjt.service.chain.ChainLog;
import com.zhjt.service.chain.TracingConstants;
@@ -45,6 +47,7 @@ import java.util.HashSet;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import mogo.telematics.pad.MessagePad;
import okio.ByteString;
@@ -61,12 +64,12 @@ import okio.ByteString;
* @UpdateRemark: 更新说明:
* @Version: 1.0
*/
public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnectListener, IPCFixationIPHelper.IIPCFixationIPListener {
public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnectListener, IPCFixationIPHelper.IIPCFixationIPListener, DispatchHandler.OnDispatchHandlerListener {
private static final String TAG = AdasChannel.class.getSimpleName();
private FpgaSocket mSocket;
private RawUnpack rawUnpack;//数据拆包
private RawUnpack rawUnpack;//业务数据拆包
private RawPack rawPack;//数据打包
private DispatchHandler dispatchHandler;//分发
private Timer checkCompatibilityTimer;//检查版本兼容性定时器 连接成功后5秒内等待工控机发送配置信息
/**
* 与工控机链接状态
@@ -79,6 +82,10 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
*/
public static final boolean isUseQueue = false;
/**
* 本通道是否启用分发线程 收发和分发拆分成两个线程
*/
public static final boolean ADAS_CHANNEL_IS_USE_DISPATCH_HANDLER = true;
/**
* 序列化rect
@@ -139,13 +146,13 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
*/
AdasChannel(AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) {
this.adasConnectStatusListener = onAdasConnectStatusListener;
initData();
//配置为null默认是乘客屏幕
if (options == null) {
this.adasOptions = new AdasOptions.Builder().setClient(true).build();
} else {
this.adasOptions = options;
}
initData();
if (!adasOptions.isClient()) {
initSocket();
}
@@ -157,7 +164,10 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
rawPack = new RawPack();
//消息工厂
myMessageFactory = new MyMessageFactory();
//司机端以及启用线程分发时
if (!adasOptions.isClient() && ADAS_CHANNEL_IS_USE_DISPATCH_HANDLER) {
dispatchHandler = new DispatchHandler(this);
}
}
/**
@@ -260,34 +270,78 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
* @param bytes 数据
*/
@Override
public void parseIPCData(byte[] bytes) {
public void decoderRaw(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return;
}
ByteString byteString = ByteString.of(bytes);
decoderRaw(byteString);
}
//数据解析以及调用分发
private void decoderRaw(ByteString byteString) {
//拆Header
try {
if (rawUnpack != null) {
RawData raw = rawUnpack.read(byteString);
if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) {
MessagePad.Header header = MessagePad.Header.parseFrom(raw.getHeader());
MessagePad.MessageType messageType = header.getMsgType();
MessagePad.Header header = MessagePad.Header.parser().parseFrom(byteString.toByteArray(), raw.getOutHeaderLength(), raw.getOffsetValue() - raw.getOutHeaderLength());
raw.setHeader(header);
//司机端刷新心跳
if (!adasOptions.isClient())
ReceiveTimeoutManager.getInstance().refreshLast(header.getTimestamp());
// CupidLogUtils.w("--->websocket byte read header = " + messageType.toString());
IMsg iMsg = myMessageFactory.createMessage(messageType);
if (iMsg == null) {
callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, bytes);
return;
//判断是否是司机屏幕,是否切换分发线程
if (!adasOptions.isClient() && ADAS_CHANNEL_IS_USE_DISPATCH_HANDLER) {
if (dispatchHandler != null)
dispatchHandler.sendRawMessage(raw);
} else {
dispatchRaw(raw);
}
iMsg.handlerMsg(header, raw.getPayload(), mAdasListener);
} else {
callError(raw.getProtocolStatus(), bytes);
callError(raw.getProtocolStatus(), byteString.toByteArray());
}
}
} catch (Exception e) {
callError(ProtocolStatus.BUSINESS_DATA_PARSE_FAILED, bytes);
CupidLogUtils.e(TAG, "原始数据:" + DigitalTrans.byte2hex(bytes), e);
callError(ProtocolStatus.HEADER_DECODE_FAILED, byteString.toByteArray());
CupidLogUtils.e(TAG, "原始数据:" + ByteUtil.byteArrToHex(byteString.toByteArray()), e);
}
}
/**
* 分发和解析
*
* @param raw
*/
private void dispatchRaw(RawData raw) {
try {
if (rawUnpack != null) {
if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) {
MessagePad.Header header = raw.getHeader();
MessagePad.MessageType messageType = header.getMsgType();
IMsg iMsg = myMessageFactory.createMessage(messageType);
if (iMsg == null) {
callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, raw.originalData.toByteArray());
return;
}
iMsg.handlerMsg(raw, mAdasListener);
} else {
callError(raw.getProtocolStatus(), raw.originalData.toByteArray());
}
}
} catch (Exception e) {
callError(ProtocolStatus.BUSINESS_DATA_PARSE_FAILED, raw.originalData.toByteArray());
CupidLogUtils.e(TAG, "原始数据:" + ByteUtil.byteArrToHex(raw.originalData.toByteArray()), e);
}
}
@Override
public void onDispatchRaw(RawData raw) {
dispatchRaw(raw);
}
private void callError(ProtocolStatus status, byte[] bytes) {
if (mAdasListener != null) {
mAdasListener.onError(status, bytes);
@@ -318,7 +372,6 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
}
}
}
}
/**
@@ -339,14 +392,6 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
}
}
private void handlerWSMsg(ByteString bytes) {
byte[] bytes1 = bytes.toByteArray();
parseIPCData(bytes1);
if (!adasOptions.isClient() && onMultiDeviceListener != null) {
onMultiDeviceListener.onForwardingIPCMessage(bytes1);
}
}
@Override
public void onConnecting(String msg) {
updateConnectStatus(Constants.IPC_CONNECTION_STATUS.CONNECTING, msg);
@@ -373,7 +418,11 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
@Override
public void onMessage(ByteString bytes) throws InvalidProtocolBufferException {
handlerWSMsg(bytes);
decoderRaw(bytes);
//乘客屏数据分发
if (!adasOptions.isClient() && onMultiDeviceListener != null) {
onMultiDeviceListener.onForwardingIPCMessage(bytes.toByteArray());
}
}
private void notFoundAddress() {
@@ -429,7 +478,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
private final OnAdasConnectStatusListener adasConnectStatusListener;
/**
* 更新连接状态
* 工控机连接状态更新
*
* @param status 状态
* @param reason 状态描述
@@ -447,10 +496,20 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
adasConnectStatusListener.onConnectionIPCStatus(ipcConnectionStatus.get(), reason);
}
if (status == Constants.IPC_CONNECTION_STATUS.CONNECTED) {
if (ADAS_CHANNEL_IS_USE_DISPATCH_HANDLER && dispatchHandler != null) {
dispatchHandler.start();
}
startCheckCompatibility();
} else {
stopCheckCompatibility();
}
if (status == Constants.IPC_CONNECTION_STATUS.DISCONNECTED) {
AdasManager.getInstance().setCarConfig(null);
if (ADAS_CHANNEL_IS_USE_DISPATCH_HANDLER && dispatchHandler != null) {
dispatchHandler.stop();
}
}
CupidLogUtils.i(TAG, "工控机连接状态 status=" + status + " reason=" + reason);
}
/**

View File

@@ -8,6 +8,7 @@ import com.zhidao.support.adas.high.bean.BaseInfo;
import com.zhidao.support.adas.high.bean.VersionCompatibility;
import com.zhidao.support.adas.high.common.AppPreferenceHelper;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import java.util.HashSet;
@@ -204,9 +205,9 @@ public class AdasManager implements IAdasNetCommApi {
* @param bytes 数据
*/
@Override
public void parseIPCData(byte[] bytes) {
public void decoderRaw(byte[] bytes) {
if (mChannel != null) {
mChannel.parseIPCData(bytes);
mChannel.decoderRaw(bytes);
}
}
@@ -439,6 +440,44 @@ public class AdasManager implements IAdasNetCommApi {
AppPreferenceHelper.getInstance(context).delIPCFixationIP();
}
/**
* 设置是否启用超时检测
* 不会存储 下次启动恢复默认
*
* @param isEnable 是否启用
*/
public void setEnableTimeoutDetection(boolean isEnable) {
ReceiveTimeoutManager.getInstance().setEnable(isEnable, getIpcConnectionStatus());
}
/**
* 获取超时检测是否启用
*
* @return 是否启用
*/
public boolean isEnableTimeoutDetection() {
return ReceiveTimeoutManager.getInstance().isEnable();
}
/**
* 设置超时检测的超时时间
* 不会存储 下次启动恢复默认
*
* @param timeout 毫秒
*/
public void setTimeoutDetectionTime(long timeout) {
ReceiveTimeoutManager.getInstance().setTimeout(timeout);
}
/**
* 获取超时检测的超时时间
*
* @return 毫秒
*/
public long getTimeoutDetectionTime() {
return ReceiveTimeoutManager.getInstance().getTimeout();
}
/**
* 发送升级指令 TODO 将会被删除
*

View File

@@ -198,7 +198,7 @@ public interface IAdasNetCommApi {
*
* @param bytes 数据
*/
void parseIPCData(byte[] bytes);
void decoderRaw(byte[] bytes);
/**
* Log是否开启打印

View File

@@ -0,0 +1,380 @@
package com.zhidao.support.adas.high.common;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ByteUtil {
private static final String TAG = ByteUtil.class.getSimpleName();
public static byte[] set8bitUnsignedValue(int num) {
return new byte[]{(byte) (num)};
}
public static byte[] set16bitUnsignedValue(int num) {
byte[] bytes = new byte[2];
bytes[0] = (byte) (num >> 8);
bytes[1] = (byte) num;
return bytes;
}
public static byte[] set32bitUnsignedValue(long num) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (num >> 24);
bytes[1] = (byte) (num >> 16);
bytes[2] = (byte) (num >> 8);
bytes[3] = (byte) num;
return bytes;
}
public static byte[] set64bitUnsignedValue(long num) {
byte[] bytes = new byte[8];
bytes[0] = (byte) (num >> 56);
bytes[1] = (byte) (num >> 48);
bytes[2] = (byte) (num >> 40);
bytes[3] = (byte) (num >> 32);
bytes[4] = (byte) (num >> 24);
bytes[5] = (byte) (num >> 16);
bytes[6] = (byte) (num >> 8);
bytes[7] = (byte) num;
return bytes;
}
/**
* 无符号
* 1 byte
* 使用后将 Index中的index移动到下一个数据的开始位
*
* @param index 开始下标
* @param data
* @return
*/
public static int get8bitUnsignedValue(int index, byte[] data) {
int value = 0;
if (data.length > index) {
value = data[index] & 0xFF;
}
return value;
}
/**
* 无符号
* 合并 2 byte
* 使用后将 Index中的index移动到下一个数据的开始位
*
* @param index 开始下标
* @param data
* @return
*/
public static int get16bitUnsignedValue(int index, byte[] data) {
// String str = "byte[]= %02X %02X";
// L.i("Index=" + index + String.format(str, data[index], data[index + 1]));
int value = 0;
if (data.length > index + 1) {
value = data[index++] & 0xFF;
value = value << 8;
value = value | (data[index] & 0xFF);
}
return value;
}
/**
* 无符号
* 合并 4 byte
* 使用后将 Index中的index移动到下一个数据的开始位
* *
*
* @param index 开始下标
* @param data
* @return
*/
public static int get32bitUnsignedValue(int index, byte[] data) {
int value = 0;
if (data.length > index + 3) {
value = data[index++] & 0xFF;
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index] & 0xFF);
}
return value;
}
/**
* 无符号
* 合并 8 byte
* 使用后将 Index中的index移动到下一个数据的开始位
*
* @param index 开始下标
* @param data
* @return
*/
/**
* 超过{@link Long#MAX_VALUE} 会产生有符号值,目前 Unit Mask 值未超过最大值
*
* @param index
* @param data
* @return
*/
public static long get64bitUnsignedValue(int index, byte[] data) {
long value = 0;
if (data.length > index + 7) {
value = data[index++] & 0xFF;
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index] & 0xFF);
}
return value;
}
/**
* 合并 8 byte
* 使用后将 Index中的index移动到下一个数据的开始位
*
* @param index 开始下标
* @param data
* @return
*/
private static final BigInteger TWO_COMPL_REF = BigInteger.ONE.shiftLeft(64);
public static String get64bitUnsignedString(int index, byte[] data) {
BigInteger bigInteger = null;
if (data.length > index + 7) {
byte[] bytes = new byte[8];
System.arraycopy(data, index, bytes, 0, 8);
bigInteger = new BigInteger(bytes);
if (bigInteger.compareTo(BigInteger.ZERO) < 0)
bigInteger = bigInteger.add(TWO_COMPL_REF);
}
return bigInteger == null ? null : bigInteger.toString();
}
/**
* 有符号
* 1 byte
*
* @param index 开始下标
* @param data
* @return
*/
public static int get8bitSignedValue(int index, byte[] data) {
int value = 0;
if (data.length > index) {
value = data[index];
}
return value;
}
/**
* 有符号
* 合并 2 byte
*
* @param index 开始下标
* @param data
* @return
*/
public static int get16bitSignedValue(int index, byte[] data) {
int value = 0;
if (data.length > index + 1) {
value = data[index++];
value = value << 8;
value = value | data[index];
}
return value;
}
/**
* 有符号
* 合并 4 byte
*
* @param index 开始下标
* @param data
* @return
*/
public static long get32bitSignedValue(int index, byte[] data) {
long value = 0L;
if (data.length > index + 3) {
value = data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index];
}
return value;
}
/**
* 有符号
* 合并 8 byte
*
* @param index 开始下标
* @param data
* @return
*/
public static long get64bitSignedValue(int index, byte[] data) {
long value = 0;
if (data.length > index + 7) {
value = data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index++];
value = value << 8;
value = value | data[index];
}
return value;
}
/**
* 判断奇数或偶数位运算最后一位是1则为奇数为0是偶数
*
* @param num
* @return
*/
public static int isOdd(int num) {
return num & 0x1;
}
/**
* Hex字符串转byte
*
* @param inHex
* @return
*/
public static byte hexToByte(String inHex) {
return (byte) Integer.parseInt(inHex, 16);
}
/**
* 转hex字符串转字节数组
*
* @param inHex
* @return
*/
public static byte[] hexToByteArr(String inHex) {
inHex = inHex.replaceAll(" ", "");
int hexlen = inHex.length();
byte[] result;
if (isOdd(hexlen) == 1) {//奇数
hexlen++;
result = new byte[(hexlen / 2)];
inHex = "0" + inHex;
} else {//偶数
result = new byte[(hexlen / 2)];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = hexToByte(inHex.substring(i, i + 2));
j++;
}
return result;
}
/**
* 1字节转2个Hex字符 无符号 不足两位
*
* @param inByte
* @return
*/
public static String byte2Hex(int inByte) {
String hex = Integer.toHexString(inByte & 0xFF).toUpperCase();
return (hex.length() == 1) ? "0" + hex : hex;
}
/**
* 字节数组转转hex字符串
*
* @param inBytArr
* @return
*/
public static String byteArrToHex(byte[] inBytArr) {
return byteArrToHex(inBytArr, true);
}
public static String byteArrToHex(byte[] inBytArr, boolean isAddSpacing) {
if (inBytArr == null)
return null;
StringBuilder strBuilder = new StringBuilder();
for (byte b : inBytArr) {
strBuilder.append(byte2Hex(b));
if (isAddSpacing)
strBuilder.append(" ");
}
return strBuilder.toString().toUpperCase().trim();
}
/**
* 拼接两个byte[]
*
* @param
* @param
* @return
*/
public static byte[] concatBytes(byte[] bt1, byte[] bt2) {
if (bt1 == null) {
return bt2;
}
if (bt2 == null) {
return bt1;
}
byte[] bt3 = new byte[bt1.length + bt2.length];
System.arraycopy(bt1, 0, bt3, 0, bt1.length);
System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
return bt3;
}
//翻转
public static String byteToBit(byte b) {
return "" + (byte) ((b >> 0) & 0x1) +
(byte) ((b >> 1) & 0x1) +
(byte) ((b >> 2) & 0x1) +
(byte) ((b >> 3) & 0x1) +
(byte) ((b >> 4) & 0x1) +
(byte) ((b >> 5) & 0x1) +
(byte) ((b >> 6) & 0x1) +
(byte) ((b >> 7) & 0x1);
}
}

View File

@@ -1,607 +0,0 @@
package com.zhidao.support.adas.high.common;
public class DigitalTrans {
/**
* 数字字符串转ASCII码字符串
*
* @param content 字符串
* @return ASCII字符串
*/
public static String StringToAsciiString(String content) {
String result = "";
int max = content.length();
for (int i = 0; i < max; i++) {
char c = content.charAt(i);
String b = Integer.toHexString(c);
result = result + b;
}
return result;
}
/**
* 十六进制转字符串
*
* @param hexString 十六进制字符串
* @param encodeType 编码类型4Unicode2普通编码
* @return 字符串
*/
public static String hexStringToString(String hexString, int encodeType) {
String result = "";
int max = hexString.length() / encodeType;
for (int i = 0; i < max; i++) {
char c = (char) DigitalTrans.hexStringToAlgorism(hexString
.substring(i * encodeType, (i + 1) * encodeType));
result += c;
}
return result;
}
/**
* 十六进制字符串装十进制
*
* @param hex 十六进制字符串
* @return 十进制数值
*/
public static int hexStringToAlgorism(String hex) {
hex = hex.toUpperCase();
int max = hex.length();
int result = 0;
for (int i = max; i > 0; i--) {
char c = hex.charAt(i - 1);
int algorism = 0;
if (c >= '0' && c <= '9') {
algorism = c - '0';
} else {
algorism = c - 55;
}
result += Math.pow(16, max - i) * algorism;
}
return result;
}
/**
* 十六转二进制
*
* @param hex 十六进制字符串
* @return 二进制字符串
*/
public static String hexStringToBinary(String hex) {
hex = hex.toUpperCase();
String result = "";
int max = hex.length();
for (int i = 0; i < max; i++) {
char c = hex.charAt(i);
switch (c) {
case '0':
result += "0000";
break;
case '1':
result += "0001";
break;
case '2':
result += "0010";
break;
case '3':
result += "0011";
break;
case '4':
result += "0100";
break;
case '5':
result += "0101";
break;
case '6':
result += "0110";
break;
case '7':
result += "0111";
break;
case '8':
result += "1000";
break;
case '9':
result += "1001";
break;
case 'A':
result += "1010";
break;
case 'B':
result += "1011";
break;
case 'C':
result += "1100";
break;
case 'D':
result += "1101";
break;
case 'E':
result += "1110";
break;
case 'F':
result += "1111";
break;
}
}
return result;
}
/**
* ASCII码字符串转数字字符串
*
* @param content ASCII字符串
* @return 字符串
*/
public static String AsciiStringToString(String content) {
String result = "";
int length = content.length() / 2;
for (int i = 0; i < length; i++) {
String c = content.substring(i * 2, i * 2 + 2);
int a = hexStringToAlgorism(c);
char b = (char) a;
String d = String.valueOf(b);
result += d;
}
return result;
}
/**
* 将十进制转换为指定长度的十六进制字符串
*
* @param algorism int 十进制数字
* @param maxLength int 转换后的十六进制字符串长度
* @return String 转换后的十六进制字符串
*/
public static String algorismToHEXString(int algorism, int maxLength) {
String result = "";
result = Integer.toHexString(algorism);
if (result.length() % 2 == 1) {
result = "0" + result;
}
return patchHexString(result.toUpperCase(), maxLength);
}
/**
* 字节数组转为普通字符串ASCII对应的字符
*
* @param bytearray byte[]
* @return String
*/
public static String bytetoString(byte[] bytearray) {
String result = "";
char temp;
int length = bytearray.length;
for (int i = 0; i < length; i++) {
temp = (char) bytearray[i];
result += temp;
}
return result;
}
/**
* 二进制字符串转十进制
*
* @param binary 二进制字符串
* @return 十进制数值
*/
public static int binaryToAlgorism(String binary) {
int max = binary.length();
int result = 0;
for (int i = max; i > 0; i--) {
char c = binary.charAt(i - 1);
int algorism = c - '0';
result += Math.pow(2, max - i) * algorism;
}
return result;
}
/**
* 十进制转换为十六进制字符串
*
* @param algorism int 十进制的数字
* @return String 对应的十六进制字符串
*/
public static String algorismToHEXString(int algorism) {
String result = "";
result = Integer.toHexString(algorism);
if (result.length() % 2 == 1) {
result = "0" + result;
}
result = result.toUpperCase();
return result;
}
/**
* HEX字符串前补0主要用于长度位数不足。
*
* @param str String 需要补充长度的十六进制字符串
* @param maxLength int 补充后十六进制字符串的长度
* @return 补充结果
*/
static public String patchHexString(String str, int maxLength) {
String temp = "";
for (int i = 0; i < maxLength - str.length(); i++) {
temp = "0" + temp;
}
str = (temp + str).substring(0, maxLength);
return str;
}
/**
* 将一个字符串转换为int
*
* @param s String 要转换的字符串
* @param defaultInt int 如果出现异常,默认返回的数字
* @param radix int 要转换的字符串是什么进制的,如16 8 10.
* @return int 转换后的数字
*/
public static int parseToInt(String s, int defaultInt, int radix) {
int i = 0;
try {
i = Integer.parseInt(s, radix);
} catch (NumberFormatException ex) {
i = defaultInt;
}
return i;
}
/**
* 将一个十进制形式的数字字符串转换为int
*
* @param s String 要转换的字符串
* @param defaultInt int 如果出现异常,默认返回的数字
* @return int 转换后的数字
*/
public static int parseToInt(String s, int defaultInt) {
int i = 0;
try {
i = Integer.parseInt(s);
} catch (NumberFormatException ex) {
i = defaultInt;
}
return i;
}
/**
* 十六进制字符串转为Byte数组,每两个十六进制字符转为一个Byte
*
* @param hex 十六进制字符串
* @return byte 转换结果
*/
public static byte[] hexStringToByte(String hex) {
int max = hex.length() / 2;
byte[] bytes = new byte[max];
String binarys = DigitalTrans.hexStringToBinary(hex);
for (int i = 0; i < max; i++) {
bytes[i] = (byte) DigitalTrans.binaryToAlgorism(binarys.substring(
i * 8 + 1, (i + 1) * 8));
if (binarys.charAt(8 * i) == '1') {
bytes[i] = (byte) (0 - bytes[i]);
}
}
return bytes;
}
/**
* 十六进制串转化为byte数组
*
* @return the array of byte
*/
public static final byte[] hex2byte(String hex)
throws IllegalArgumentException {
if (hex.length() % 2 != 0) {
throw new IllegalArgumentException();
}
char[] arr = hex.toCharArray();
byte[] b = new byte[hex.length() / 2];
for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
String swap = "" + arr[i++] + arr[i];
int byteint = Integer.parseInt(swap, 16) & 0xFF;
b[j] = new Integer(byteint).byteValue();
}
return b;
}
/**
* 字节数组转换为十六进制字符串
*
* @param b byte[] 需要转换的字节数组
* @return String 十六进制字符串
*/
public static final String byte2hex(byte b[]) {
if (b == null) {
return "";
}
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0xff);
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 字符串转换成十六进制字符串
*
* @param String str 待转换的ASCII字符串
* @return String 每个Byte之间空格分隔如: [61 6C 6B]
*/
public static String str2HexStr(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
sb.append(' ');
}
return sb.toString().trim();
}
/**
* 十六进制转换字符串
*
* @param String str Byte字符串(Byte之间无分隔符 如:[616C6B])
* @return String 对应的字符串
*/
public static String hexStr2Str(String hexStr) {
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xff);
}
return new String(bytes);
}
/**
* bytes转换成十六进制字符串
*
* @param byte[] b byte数组
* @return String 每个Byte值之间空格分隔
*/
public static String byte2HexStr(byte[] b) {
String stmp = "";
StringBuilder sb = new StringBuilder("");
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0xFF);
sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
sb.append(" ");
}
return sb.toString().toUpperCase().trim();
}
/**
* bytes字符串转换为Byte值
*
* @param String src Byte字符串每个Byte之间没有分隔符
* @return byte[]
*/
public static byte[] hexStr2Bytes(String src) {
int m = 0, n = 0;
int l = src.length() / 2;
System.out.println(l);
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
m = i * 2 + 1;
n = m + 1;
ret[i] = Byte.decode("0x" + src.substring(i * 2, m) + src.substring(m, n));
}
return ret;
}
/**
* String的字符串转换成unicode的String
*
* @param String strText 全角字符串
* @return String 每个unicode之间无分隔符
* @throws Exception
*/
public static String strToUnicode(String strText)
throws Exception {
char c;
StringBuilder str = new StringBuilder();
int intAsc;
String strHex;
for (int i = 0; i < strText.length(); i++) {
c = strText.charAt(i);
intAsc = (int) c;
strHex = Integer.toHexString(intAsc);
if (intAsc > 128)
str.append("\\u" + strHex);
else // 低位在前面补00
str.append("\\u00" + strHex);
}
return str.toString();
}
/**
* unicode的String转换成String的字符串
*
* @param String hex 16进制值字符串 一个unicode为2byte
* @return String 全角字符串
*/
public static String unicodeToString(String hex) {
int t = hex.length() / 6;
StringBuilder str = new StringBuilder();
for (int i = 0; i < t; i++) {
String s = hex.substring(i * 6, (i + 1) * 6);
// 高位需要补上00再转
String s1 = s.substring(2, 4) + "00";
// 低位直接转
String s2 = s.substring(4);
// 将16进制的string转为int
int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
// 将int转换为字符
char[] chars = Character.toChars(n);
str.append(new String(chars));
}
return str.toString();
}
/**
* 整型数据拆分为长度为2的字节数组低8位存放在序号小的元素高8位存放在序号大的元素中(大端存储)
*
* @param data
* @return
*/
public static byte[] intTo2Byte(int data) {
byte[] byteArray = new byte[2];
byteArray[0] = (byte) (data >> 8);
byteArray[1] = (byte) data;
return byteArray;
}
/**
* 将两个字节拼接还原成无符号的整型数据
* 数据域中的数据都按小端存储示例数据0x1234则Byte0为0x34,Byte1为0x12
*
* @param byte1
* @param byte2
* @return
*/
public static int joint2ByteToInt(byte byte1, byte byte2) {
int result = byte1 & 0xFF;
result = (result << 8) | (0x00FF & byte2);
return result;
}
/**
* 拼接两个byte[]
*
* @param
* @param
* @return
*/
public static byte[] concatBytes(byte[] bt1, byte[] bt2) {
if (bt1 == null) {
return bt2;
}
if (bt2 == null) {
return bt1;
}
byte[] bt3 = new byte[bt1.length + bt2.length];
System.arraycopy(bt1, 0, bt3, 0, bt1.length);
System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
return bt3;
}
//获得本机cpu大小端
public static boolean isBigendian() {
short i = 0x1;
boolean bRet = ((i >> 8) == 0x1);
return bRet;
}
/**
* 无符号
* 1 byte
*
* @param data
* @return
*/
public static int get8bitUnsignedValue(byte[] data) {
int value = 0;
int index = 0;
if (data.length > index) {
value = data[index] & 0xFF;
}
return value;
}
/**
* 无符号
* 合并 2 byte
*
* @param data
* @return
*/
public static int get16bitUnsignedValue(byte[] data) {
int value = 0;
int index = 0;
if (data.length > index + 1) {
value = data[index++] & 0xFF;
value = value << 8;
value = value | (data[index] & 0xFF);
}
return value;
}
/**
* 无符号
* 合并 4 byte
*
* @param data
* @return
*/
public static long get32bitUnsignedValue(byte[] data) {
long value = 0L;
int index = 0;
if (data.length > index + 3) {
value = data[index++] & 0xFF;
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index++] & 0xFF);
value = value << 8;
value = value | (data[index] & 0xFF);
}
return value;
}
public static byte[] set8bitUnsignedValue(int num) {
return new byte[]{(byte) (num)};
}
public static byte[] set16bitUnsignedValue(int num) {
byte[] bytes = new byte[2];
bytes[0] = (byte) (num >> 8);
bytes[1] = (byte) num;
return bytes;
}
public static byte[] set32bitUnsignedValue(long num) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (num >> 24);
bytes[1] = (byte) (num >> 16);
bytes[2] = (byte) (num >> 8);
bytes[3] = (byte) num;
return bytes;
}
public static byte[] set64bitUnsignedValue(long num) {
byte[] bytes = new byte[8];
bytes[0] = (byte) (num >> 56);
bytes[1] = (byte) (num >> 48);
bytes[2] = (byte) (num >> 40);
bytes[3] = (byte) (num >> 32);
bytes[4] = (byte) (num >> 24);
bytes[5] = (byte) (num >> 16);
bytes[6] = (byte) (num >> 8);
bytes[7] = (byte) num;
return bytes;
}
}

View File

@@ -10,7 +10,8 @@ public enum ProtocolStatus {
MAGIC_CODE_CHECK_FAILED(0x01, "数据头校验失败"),
PACKAGE_LENGTH_CHECK_FAILED(0x02, "数据包长度校验失败"),
MESSAGE_TYPE_UNKNOWN(0x03, "MessageType未知"),
BUSINESS_DATA_PARSE_FAILED(0x04, "业务数据解析失败");
HEADER_DECODE_FAILED(0x04, "Header解析失败"),
BUSINESS_DATA_PARSE_FAILED(0x05, "业务数据解析失败");
public final int code;

View File

@@ -11,10 +11,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public class ReceiveTimeoutManager {
private static final String TAG = ReceiveTimeoutManager.class.getSimpleName();
private static final long DEFAULT_TIMEOUT = 4 * 1000L;//默认超时时间
private static volatile ReceiveTimeoutManager INSTANCE;
private static final long DEFAULT_TIMEOUT = 3 * 1000L;//默认超时时间
private final AtomicBoolean isEnable = new AtomicBoolean(true);//是否启用超时检测
private volatile long lastReceiveTime;
private long timeout = DEFAULT_TIMEOUT;//可配置超时时间
private double lastReceiveTime;//double 秒
private long timeoutPeriod;//超时时间,最后一次接收时间 + timeout
private OnTimeoutListener listener;
private volatile Timer timer;
@@ -53,7 +55,7 @@ public class ReceiveTimeoutManager {
public void setEnable(boolean isEnable, @Define.IPCConnectionStatus int ipcConnectionStatus) {
this.isEnable.set(isEnable);
//如果启动并且当前已连接
if (isEnable) {
if (this.isEnable.get()) {
if (ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.CONNECTED)
start();
} else {
@@ -61,32 +63,54 @@ public class ReceiveTimeoutManager {
}
}
/**
* 超时时间
*
* @param timeout 毫秒
*/
public void setTimeout(long timeout) {
//如果一启动 停止再启动 新timeout如果小于当前 老timeout将有可能出现时间差计算出错的情况
if (timeout < 1000L) {
timeout = 1000L;
}
this.timeout = timeout;
if (timer != null) {
stop();
start();
}
}
public long getTimeout() {
return timeout;
}
/**
* 刷新最后一次接收数据时间
*/
public void refreshLast() {
public void refreshLast(double timestamp) {
if (isEnable.get())
lastReceiveTime = System.currentTimeMillis();
lastReceiveTime = timestamp;
}
public synchronized void start() {
if (isEnable.get())
if (timer == null) {
refreshLast();
refreshLast(System.currentTimeMillis() / 1000.0D);
timeoutPeriod = ((long) lastReceiveTime * 1000) + timeout;
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
long difference = System.currentTimeMillis() - lastReceiveTime;
long difference = timeoutPeriod - ((long) lastReceiveTime * 1000);
timeoutPeriod = ((long) lastReceiveTime * 1000) + timeout;
CupidLogUtils.e(TAG, "最后一次接收工控机数据时间与当前时间差=" + (difference / 1000.0) + "");
if (difference >= DEFAULT_TIMEOUT) {
if (difference >= timeout) {
if (listener != null) {
listener.onTimeout(difference / 1000.0);
}
}
}
}, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);//延时
}, timeout, timeout);//延时
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -16,14 +17,12 @@ public class ArrivalNotificationMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.ArrivalNotification arrivalNotification = MessagePad.ArrivalNotification.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.ArrivalNotification arrivalNotification = MessagePad.ArrivalNotification.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onArrivalNotification(header, arrivalNotification);
adasListener.onArrivalNotification(raw.getHeader(), arrivalNotification);
}
// CupidLogUtils.e("到站提醒--->" + arrivalNotification.toString());
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -16,13 +17,11 @@ public class AutopilotStateMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.AutopilotState autopilotState = MessagePad.AutopilotState.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.AutopilotState autopilotState = MessagePad.AutopilotState.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onAutopilotState(header, autopilotState);
adasListener.onAutopilotState(raw.getHeader(), autopilotState);
}
// CupidLogUtils.e("自动驾驶状态--->" + autopilotState.toString());
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -16,13 +17,11 @@ public class BasicInfoReqMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.BasicInfoReq autopilotState = MessagePad.BasicInfoReq.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.BasicInfoReq autopilotState = MessagePad.BasicInfoReq.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onBasicInfoReq(header, autopilotState);
adasListener.onBasicInfoReq(raw.getHeader(), autopilotState);
}
// CupidLogUtils.e("自动驾驶设备基础信息请求--->" + autopilotState.toString());
}
}

View File

@@ -5,6 +5,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.AdasManager;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -18,14 +19,12 @@ public class CarConfigRespMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.CarConfigResp carConfigResp = MessagePad.CarConfigResp.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.CarConfigResp carConfigResp = MessagePad.CarConfigResp.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
AdasManager.getInstance().setCarConfig(carConfigResp);
if (adasListener != null) {
adasListener.onCarConfigResp(header, carConfigResp);
adasListener.onCarConfigResp(raw.getHeader(), carConfigResp);
}
CupidLogUtils.e("车机基础信息应答--->" + carConfigResp.toString());
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -16,13 +17,11 @@ public class GlobalPathRespMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.GlobalPathResp globalPathResp = MessagePad.GlobalPathResp.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.GlobalPathResp globalPathResp = MessagePad.GlobalPathResp.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onGlobalPathResp(header, globalPathResp);
adasListener.onGlobalPathResp(raw.getHeader(), globalPathResp);
}
// CupidLogUtils.e("自动驾驶路径应答--->" + globalPathResp.toString());
}
}

View File

@@ -1,9 +1,10 @@
package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -17,14 +18,11 @@ public class GnssInfoMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
ReceiveTimeoutManager.getInstance().refreshLast();
MessagePad.GnssInfo trajectory = MessagePad.GnssInfo.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.GnssInfo trajectory = MessagePad.GnssInfo.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onGnssInfo(header, trajectory);
adasListener.onGnssInfo(raw.getHeader(), trajectory);
}
// CupidLogUtils.e("惯导信息--->" + trajectory.toString());
}
}

View File

@@ -3,8 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import mogo.telematics.pad.MessagePad;
import com.zhidao.support.adas.high.protocol.RawData;
/**
* @author nie yunlong
@@ -19,6 +18,13 @@ public interface IMsg {
*/
void handlerMsg(Gson gson, OnAdasListener adasListener, String msg);
void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException;
/**
* 分发处理
*
* @param raw 原始数据
* @param adasListener 监听
* @throws InvalidProtocolBufferException
*/
void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException;
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -19,7 +20,7 @@ public class NuImplMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import perception.ObjectOuterClass;
/**
@@ -17,12 +17,10 @@ public class PerceptionObstaclesMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
ObjectOuterClass.TrackedObjects trackedObjects = ObjectOuterClass.TrackedObjects.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
ObjectOuterClass.TrackedObjects trackedObjects = ObjectOuterClass.TrackedObjects.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onTrackedObjects(header, trackedObjects);
adasListener.onTrackedObjects(raw.getHeader(), trackedObjects);
}
}
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import perception.TrafficLightOuterClass;
/**
@@ -17,12 +17,10 @@ public class PerceptionTrafficLightMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
TrafficLightOuterClass.TrafficLights trafficLights = TrafficLightOuterClass.TrafficLights.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
TrafficLightOuterClass.TrafficLights trafficLights = TrafficLightOuterClass.TrafficLights.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onPerceptionTrafficLight(header, trafficLights);
adasListener.onPerceptionTrafficLight(raw.getHeader(), trafficLights);
}
}
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import rule_segement.PointCloud;
/**
@@ -17,12 +17,10 @@ public class PointCloudMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
PointCloud.LidarPointCloud pointCloud = PointCloud.LidarPointCloud.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
PointCloud.LidarPointCloud pointCloud = PointCloud.LidarPointCloud.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onPointCloud(header, pointCloud);
adasListener.onPointCloud(raw.getHeader(), pointCloud);
}
}
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import prediction.Prediction;
/**
@@ -17,12 +17,10 @@ public class PredictionObstacleTrajectoryMessage extends MyAbstractMessageHandle
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
Prediction.mPredictionObjects objects = Prediction.mPredictionObjects.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
Prediction.mPredictionObjects objects = Prediction.mPredictionObjects.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onPredictionObstacleTrajectory(header, objects);
adasListener.onPredictionObstacleTrajectory(raw.getHeader(), objects);
}
}
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
/**
@@ -17,13 +17,11 @@ public class RecordResultMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
RecordPanelOuterClass.RecordPanel recordPanel = RecordPanelOuterClass.RecordPanel.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
RecordPanelOuterClass.RecordPanel recordPanel = RecordPanelOuterClass.RecordPanel.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onRecordResult(header, recordPanel);
adasListener.onRecordResult(raw.getHeader(), recordPanel);
}
// CupidLogUtils.e("数据采集结果--->" + recordPanel.toString());
// CupidLogUtils.e("数据采集结果--->" + recordPanel.toString());;
}
}

View File

@@ -3,8 +3,8 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
/**
@@ -17,12 +17,10 @@ public class ReportMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MogoReportMsg.MogoReportMessage mogoReportMessage = MogoReportMsg.MogoReportMessage.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MogoReportMsg.MogoReportMessage mogoReportMessage = MogoReportMsg.MogoReportMessage.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onReportMessage(header, mogoReportMessage);
adasListener.onReportMessage(raw.getHeader(), mogoReportMessage);
}
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -19,13 +20,11 @@ public class TrackedObjectsMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.TrackedObjects trackedObjects = MessagePad.TrackedObjects.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.TrackedObjects trackedObjects = MessagePad.TrackedObjects.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onTrackedObjects(header, trackedObjects);
adasListener.onTrackedObjects(raw.getHeader(), trackedObjects);
}
// CupidLogUtils.e("障碍物信息--->" + trackedObjects.toString());
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -16,13 +17,11 @@ public class TrajectoryMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.Trajectory trajectory = MessagePad.Trajectory.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.Trajectory trajectory = MessagePad.Trajectory.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onTrajectory(header, trajectory);
adasListener.onTrajectory(raw.getHeader(), trajectory);
}
// CupidLogUtils.e("车前引导线--->" + trajectory.toString());
}
}

View File

@@ -3,9 +3,9 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import chassis.VehicleStateOuterClass;
import mogo.telematics.pad.MessagePad;
/**
* 底盘信息, 透传底盘状态pb参考底盘
@@ -17,13 +17,11 @@ public class VehicleStateMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
VehicleStateOuterClass.VehicleState vehicleState = VehicleStateOuterClass.VehicleState.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
VehicleStateOuterClass.VehicleState vehicleState = VehicleStateOuterClass.VehicleState.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onVehicleState(header, vehicleState);
adasListener.onVehicleState(raw.getHeader(), vehicleState);
}
// CupidLogUtils.e("底盘信息--->" + vehicleState.toString());
}
}

View File

@@ -3,6 +3,7 @@ package com.zhidao.support.adas.high.msg;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.protocol.RawData;
import mogo.telematics.pad.MessagePad;
@@ -17,13 +18,11 @@ public class WarnMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.Warn warn = MessagePad.Warn.parseFrom(msg);
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.Warn warn = MessagePad.Warn.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
if (adasListener != null) {
adasListener.onWarn(header, warn);
adasListener.onWarn(raw.getHeader(), warn);
}
// CupidLogUtils.e("预警数据--->" + warn.toString());
}
}

View File

@@ -4,8 +4,7 @@ import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.OnAdasListener;
import com.zhidao.support.adas.high.bean.IPCUpgradeStateInfo;
import mogo.telematics.pad.MessagePad;
import com.zhidao.support.adas.high.protocol.RawData;
/**
* @des 工控机升级状态 之后版本会被替换成PB格式
@@ -24,7 +23,7 @@ public class WsAutopilotUpgradeStatusMessage extends MyAbstractMessageHandler {
}
@Override
public void handlerMsg(MessagePad.Header header, byte[] msg, OnAdasListener adasListener) throws InvalidProtocolBufferException {
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
}

View File

@@ -42,7 +42,7 @@ public class DefaultMessageProtocol implements IMessageProtocol {
* @return
*/
@Override
public int getOutHeader() {
public int getOutHeaderLength() {
return getMagicCodeLength() + getPackageLength() + getOffsetLength();
}
@@ -58,7 +58,7 @@ public class DefaultMessageProtocol implements IMessageProtocol {
if (offsetValue == 0) {
return offsetValue;
}
return offsetValue - getOutHeader();
return offsetValue - getOutHeaderLength();
}
/**

View File

@@ -21,7 +21,7 @@ public interface IMessageProtocol {
*/
int getPackageLength();
int getOutHeader();
int getOutHeaderLength();
/**
* 获取header数据长度

View File

@@ -1,8 +1,11 @@
package com.zhidao.support.adas.high.protocol;
import com.zhidao.support.adas.high.common.DigitalTrans;
import com.zhidao.support.adas.high.common.ByteUtil;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import mogo.telematics.pad.MessagePad;
import okio.ByteString;
/**
* 原始数据协议
*
@@ -12,9 +15,12 @@ import com.zhidao.support.adas.high.common.ProtocolStatus;
* 原始数据格式MagicCode(2字节 6d67) 偏移量(2字节 从原始数据头开始一直到Body头) 数据包总长度4字节 Header Body
*/
public class RawData {
/**
* 数据拆包是否成功
* 原始数据
*/
public final ByteString originalData;
/**
* 数据拆包状态
*/
private ProtocolStatus protocolStatus;
@@ -23,7 +29,10 @@ public class RawData {
* mg=0x6d67
*/
private byte[] magicCode;
/**
* MG长度+数据包长度+偏移量长度
*/
private int outHeaderLength;
/**
* 偏移量用于计算header长度
*/
@@ -39,20 +48,17 @@ public class RawData {
/**
* 包长度
*/
private long packageLengthValue;
private int packageLengthValue;
/**
* 头部消息,装载消息类型等
* 长度=offset-out_header.length
*/
private byte[] header;
private MessagePad.Header header;
/**
* 负载数据:真实上报的数据
*/
private byte[] payload;
public RawData() {
public RawData(ByteString originalData) {
this.originalData = originalData;
}
/**
@@ -61,8 +67,8 @@ public class RawData {
* 固定8个字节否则出错。
*/
public byte[] getOutHeaderBytes() {
byte[] bytes = DigitalTrans.concatBytes(getMagicCode(), getOffset());
byte[] outHeader = DigitalTrans.concatBytes(bytes, getPackageLength());
byte[] bytes = ByteUtil.concatBytes(getMagicCode(), getOffset());
byte[] outHeader = ByteUtil.concatBytes(bytes, getPackageLength());
return outHeader;
}
@@ -75,6 +81,13 @@ public class RawData {
this.magicCode = magicCode;
}
public int getOutHeaderLength() {
return outHeaderLength;
}
public void setOutHeaderLength(int outHeaderLength) {
this.outHeaderLength = outHeaderLength;
}
public byte[] getOffset() {
return offset;
@@ -89,33 +102,24 @@ public class RawData {
return packageLength;
}
public void setPackageLength(byte[] packageLength, long packageLengthValue) {
public void setPackageLength(byte[] packageLength, int packageLengthValue) {
this.packageLength = packageLength;
this.packageLengthValue = packageLengthValue;
}
public byte[] getHeader() {
public MessagePad.Header getHeader() {
return header;
}
public void setHeader(byte[] header) {
public void setHeader(MessagePad.Header header) {
this.header = header;
}
public byte[] getPayload() {
return payload;
}
public void setPayload(byte[] payload) {
this.payload = payload;
}
public int getOffsetValue() {
return offsetValue;
}
public long getPackageLengthValue() {
public int getPackageLengthValue() {
return packageLengthValue;
}
@@ -133,8 +137,7 @@ public class RawData {
offset = null;
offsetValue = 0;
packageLength = null;
packageLengthValue = 0L;
packageLengthValue = 0;
header = null;
payload = null;
}
}

View File

@@ -1,7 +1,7 @@
package com.zhidao.support.adas.high.protocol;
import com.zhidao.support.adas.high.common.ByteUtil;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.DigitalTrans;
import java.util.concurrent.atomic.AtomicLong;
@@ -37,7 +37,7 @@ public class RawPack {
headerBuilder.setTimestamp(time);
headerBuilder.setSourceTimestamp(time);
MessagePad.Header headerPb = headerBuilder.build();
int lengthValue = messageProtocol.getOutHeader() + headerPb.getSerializedSize();//数据总长度
int lengthValue = messageProtocol.getOutHeaderLength() + headerPb.getSerializedSize();//数据总长度
byte[] offset = getOffset(lengthValue);
if (data != null && data.length > 0) {
lengthValue += data.length;
@@ -52,10 +52,10 @@ public class RawPack {
//添加数据包长度
System.arraycopy(length, 0, msg, messageProtocol.getMagicCodeLength() + messageProtocol.getOffsetLength(), messageProtocol.getPackageLength());
//添加Header
System.arraycopy(header, 0, msg, messageProtocol.getOutHeader(), header.length);
System.arraycopy(header, 0, msg, messageProtocol.getOutHeaderLength(), header.length);
//添加数据
if (data != null && data.length > 0) {
System.arraycopy(data, 0, msg, messageProtocol.getOutHeader() + header.length, data.length);
System.arraycopy(data, 0, msg, messageProtocol.getOutHeaderLength() + header.length, data.length);
}
return ByteString.of(msg);
@@ -67,7 +67,7 @@ public class RawPack {
* @return
*/
private byte[] getOffset(int offsetValue) {
return DigitalTrans.set16bitUnsignedValue(offsetValue);
return ByteUtil.set16bitUnsignedValue(offsetValue);
}
/**
@@ -76,6 +76,6 @@ public class RawPack {
* @return
*/
private byte[] getPackageLength(long lengthValue) {
return DigitalTrans.set32bitUnsignedValue(lengthValue);
return ByteUtil.set32bitUnsignedValue(lengthValue);
}
}

View File

@@ -1,7 +1,7 @@
package com.zhidao.support.adas.high.protocol;
import com.zhidao.support.adas.high.common.ByteUtil;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.DigitalTrans;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import java.util.Arrays;
@@ -18,21 +18,19 @@ import okio.ByteString;
public class RawUnpack {
private static final String TAG = RawUnpack.class.getSimpleName();
private final DefaultMessageProtocol messageProtocol;
private RawData originalData;
public RawUnpack() {
messageProtocol = new DefaultMessageProtocol();
}
public RawData read(ByteString bytes) {
if (originalData == null)
originalData = new RawData();
RawData originalData = new RawData(bytes);
unpack(bytes, originalData);
return originalData;
}
private synchronized void unpack(ByteString bytes, RawData raw) {
private void unpack(ByteString bytes, RawData raw) {
// CupidLogUtils.w(TAG, "WS 原始数据=" + bytes.hex());
//读取magicCode
ByteString magicCode;
@@ -46,14 +44,15 @@ public class RawUnpack {
// CupidLogUtils.w(TAG, "WS MagicCode=" + magicCode.hex());
if (Arrays.equals(magicCode.toByteArray(), Constants.RAW_MG)) {
int offsetLength = messageProtocol.getOffsetLength();
int outHeader = messageProtocol.getOutHeader();
int outHeaderLength = messageProtocol.getOutHeaderLength();
raw.setOutHeaderLength(outHeaderLength);
//读取offset
ByteString offset = bytes.substring(magicCodeLength, magicCodeLength + offsetLength);
byte[] offsetB = offset.toByteArray();
raw.setOffset(offsetB, getOffsetValue(offsetB));
// CupidLogUtils.w(TAG, "WS 偏移量 bytes=" + offset.hex() + " 偏移量=" + raw.getOffsetValue());
//读取packageLength
ByteString packageLength = bytes.substring(magicCodeLength + offsetLength, outHeader);
ByteString packageLength = bytes.substring(magicCodeLength + offsetLength, outHeaderLength);
byte[] packageLengthB = packageLength.toByteArray();
raw.setPackageLength(packageLengthB, getPackageLengthValue(packageLengthB));
if (bytes.size() != raw.getPackageLengthValue()) {
@@ -61,14 +60,8 @@ public class RawUnpack {
raw.clear();
return;
}
// CupidLogUtils.w(TAG, "WS 数据包从长度 bytes=" + packageLength.hex() + " 数据包从长度=" + raw.getPackageLengthValue());
//读取header
ByteString header = bytes.substring(outHeader, raw.getOffsetValue());
raw.setHeader(header.toByteArray());
// CupidLogUtils.w(TAG, "WS Header=" + header.hex());
//读取payload
ByteString payload = bytes.substring(raw.getOffsetValue());
raw.setPayload(payload.toByteArray());
raw.setProtocolStatus(ProtocolStatus.SUCCEED);
// CupidLogUtils.w(TAG, "WS IPC数据=" + payload.hex() + " IPC数据长度=" + messageProtocol.getPayloadLength(raw.getPackageLengthValue(), raw.getOffsetValue()));
} else {
@@ -87,7 +80,7 @@ public class RawUnpack {
if (offset == null || offset.length != 2) {
return 0;
}
return DigitalTrans.get16bitUnsignedValue(offset);
return ByteUtil.get16bitUnsignedValue(0, offset);
}
/**
@@ -95,10 +88,10 @@ public class RawUnpack {
*
* @return
*/
private long getPackageLengthValue(byte[] length) {
private int getPackageLengthValue(byte[] length) {
if (length == null || length.length != 4) {
return 0;
}
return DigitalTrans.get32bitUnsignedValue(length);
return ByteUtil.get32bitUnsignedValue(0, length);
}
}

View File

@@ -0,0 +1,126 @@
package com.zhidao.support.adas.high.thread;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;
import com.zhidao.support.adas.high.protocol.RawData;
import java.lang.ref.WeakReference;
import okio.ByteString;
/**
* 将WebSocket线程分发到工作线程
*/
public class DispatchHandler {
public static final int WHAT_DISPATCH_RAW = 0x01;//分发消息 what
private HandlerThread mThread;
private BaseHandler mBaseHandler;
private OnDispatchHandlerListener listener;
public interface OnDispatchHandlerListener {
void onDispatchRaw(RawData raw);
}
public DispatchHandler(@NonNull OnDispatchHandlerListener listener) {
this.listener = listener;
}
public void start() {
if (mThread == null) {
mThread = new HandlerThread("IPCEventDispatchHandler");
mThread.start();
initHandler(mThread.getLooper());
}
}
public void stop() {
if (mBaseHandler != null) {
mBaseHandler.removeCallbacksAndMessages(null);
mBaseHandler = null;
}
if (mThread != null) {
mThread.quit();
mThread = null;
}
}
public void sendRawMessage(RawData raw) {
if (mBaseHandler != null) {
Message msg = Message.obtain();
msg.what = WHAT_DISPATCH_RAW;
msg.obj = raw;
mBaseHandler.sendMessage(msg);
}
}
/**
* 同Handler 的 handleMessage
* getHandler.sendMessage,发送的Message在此接收
* 在此之前确定已经调用initHandler
*
* @param msg
*/
protected void handleMessage(Message msg) {
if (msg.what == WHAT_DISPATCH_RAW) {
if (listener != null) {
listener.onDispatchRaw((RawData) msg.obj);
}
}
}
/**
* 初始化一个Handler如果需要使用Handler先调用此方法
* 然后可以使用postRunnable(Runnable runnable)
* sendMessage在handleMessageMessage msg中接收msg
*/
private void initHandler(@NonNull Looper looper) {
mBaseHandler = new BaseHandler(looper, this);
}
/**
* 同Handler的postRunnable
* 在此之前确定已经调用initHandler
*/
public void postRunnable(Runnable runnable) {
postRunnableDelayed(runnable, 0);
}
/**
* 同Handler的postRunnableDelayed
* 在此之前确定已经调用initHandler
*/
public void postRunnableDelayed(Runnable runnable, long delayMillis) {
if (mBaseHandler != null)
mBaseHandler.postDelayed(runnable, delayMillis);
}
protected static class BaseHandler extends Handler {
private final WeakReference<DispatchHandler> mObjects;
public BaseHandler(@NonNull Looper looper, DispatchHandler mPresenter) {
super(looper);
mObjects = new WeakReference<DispatchHandler>(mPresenter);
}
@Override
public void handleMessage(Message msg) {
DispatchHandler mPresenter = mObjects.get();
if (mPresenter != null)
mPresenter.handleMessage(msg);
}
}
}