hxb
2022-02-16 11cea3249fd58d59d7c1d644b1cfff6a547921c2
Merge branch 'dev-hxb'
6个文件已添加
3个文件已删除
18个文件已修改
934 ■■■■■ 已修改文件
HDLSDK.zip 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-common/build.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/build.gradle 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AuthenticateRequest.java 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BroadcastRequest.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/PropertyReadRequest.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/build.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java 288 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO.zip 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-common-V1.0.2.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-common-V1.0.3.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.2.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.3.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.2.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.3.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK.zip
Binary files differ
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -71,7 +71,10 @@
        super.onDestroy();
        removeAllTopicsListener();
    }
void init(){
    HDLLinkConfig.getInstance().setLocalSecret("7d04c4e3c2b7d600");
    HDLLinkConfig.getInstance().setGatewayId("1473119283609321473");
}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
@@ -80,9 +83,9 @@
        tv = findViewById(R.id.state_tv);
        rv = findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(this));
         init();
        checkIfCertified();
        initDeviceInfo();
        registerAllTopicsListener();
        ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
@@ -202,6 +205,7 @@
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse) msg;
                handleLinkResponse(response);
            }
        };
        HDLLink.getInstance().registerAllTopicsListener(allTopicsListener);
@@ -250,6 +254,24 @@
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    void initDeviceInfo()
    {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("123456789");
        infoBean.setIPMAC("12345678900");
        infoBean.setDeviceName("音乐播放器");//设备名字
        infoBean.setDeviceModel("MCLog.431");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.88.1");
        infoBean.setIPAddress("192.168.88.100");
        infoBean.setGateway_type("music.standard");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE08");
        infoBean.setSid("010105000000FE08110100000000");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /**
     * 入网认证
     */
@@ -262,7 +284,7 @@
        String macStr = "AA000000000000BB";//设备唯一MAC地址
        String secret = "87ae414b7a853f65";//通过spk和mac提交云端认证后分配的secret
        //正式服务器
//        //正式服务器
//        String spkStr = "screen.mirror";//产品spk
//        String macStr = "AA000000000000AC";//设备唯一MAC地址
//        String secret = "ee62124c151b737c";//通过spk和mac提交云端认证后分配的secret
@@ -290,13 +312,14 @@
        infoBean.setDeviceModel("HDL");//
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.88.1");
        infoBean.setIPAddress(IpUtils.getIP(this));
        infoBean.setIPAddress(IpUtils.getIP(this));//根据真实的IP地址填写
        infoBean.setOID("010105000000FE08");
        infoBean.setSid("010105000000FE08110100000000");
        infoBean.setHw_version("1.0");
        infoBean.setFw_version("1.0");
//        infoBean.set
        AuthenticateRequest.VersionBean[] versionBeans = new AuthenticateRequest.VersionBean[]{new AuthenticateRequest.VersionBean("FW", versionString), new AuthenticateRequest.VersionBean("HW", "1956F")};
        infoBean.setVersions(versionBeans);
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, infoBean, authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
            @Override
HDLSDK/hdl-common/build.gradle
@@ -9,7 +9,7 @@
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 2
        versionName "1.0.2"
        versionName "1.0.5"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java
@@ -77,4 +77,14 @@
    //8.6场景删除
    public static final String SCENE_DELETE = "/user/%s/custom/scene/delete";
    /**
     * 设备连接TCP之前广播
     */
    public static final String BROADCAST="/user/all/custom/gateway/broadcast";
    /**
     * 主网关回复
     */
    public static final String BROADCAST_REPLY="/user/all/custom/gateway/broadcast_reply";
}
HDLSDK/hdl-connect/build.gradle
@@ -8,8 +8,8 @@
    defaultConfig {
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 3
        versionName "1.0.2"
        versionCode 2
        versionName "1.0.5"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
@@ -44,4 +44,4 @@
//    //加密
//    implementation 'cn.hutool:hutool-all:5.6.5'
//    implementation 'org.bouncycastle:bcprov-jdk15on:1.60'
}
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java
@@ -177,14 +177,25 @@
    }
    /**
     * 通用UDP广播发送指令
     * 通用UDP发送指令
     * 1秒没响应就让他重新发送,重试3次
     * @param topic 发送数据
     * @param bodyStr body内容
     * @param callBack 回调
     */
    public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr, callBack);
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,false, callBack);
    }
    /**
     * 通用广播UDP发送指令
     * 1秒没响应就让他重新发送,重试3次
     * @param topic 发送数据
     * @param bodyStr body内容
     * @param callBack 回调
     */
    public void udpBroadcastSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,true, callBack);
    }
    /**
@@ -206,7 +217,17 @@
     * @param bodyStr  回复的主题
     */
    public void udpSendMsg(String topic, String bodyStr) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr);
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,false);
    }
    /**
     * 通用广播发送指令 只发一次,不监听回复,不重发
     *
     * @param topic    发送数据
     * @param bodyStr  回复的主题
     */
    public void udpBroadcastSendMsg(String topic, String bodyStr) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,true);
    }
    /**
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java
@@ -4,6 +4,7 @@
import androidx.annotation.NonNull;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import com.hdl.sdk.common.utils.ByteUtils;
import com.hdl.sdk.connect.utils.AesUtil;
@@ -87,6 +88,7 @@
                String headString = "Topic:" + getTopic() + "\r\n" + "Length:" + dataBytes.length + "\r\n" + "\r\n";
                byte[] headBytes = headString.getBytes("utf-8");
                byte[] sendBytes = ByteUtils.concatBytes(headBytes, dataBytes);
                LogUtils.i(headString + "\r\n" + data);
                return sendBytes;
            } else {
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AuthenticateRequest.java
@@ -34,15 +34,45 @@
        this.auth = auth;
    }
    /**
     * 认证信息
     */
    public static class AuthBean implements Serializable {
        /**
         * 设备MACKey
         */
        private String mac_key;//(mac+secret)的两次md5值
        /**
         * 设备spk
         */
        private String spk;
        /**
         * 请求信息
         */
        private RequestBean request;//设备相关信息
        /**
         * MAC key
         * @return
         */
        public String getMACKey() { return mac_key; }
        /**
         * MACkey
         * @param value
         */
        public void setMACKey(String value) { this.mac_key = value; }
        /**
         * SPK
         * @return
         */
        public String getSpk() { return spk; }
        /**
         * SPK
         * @param value
         */
        public void setSpk(String value) { this.spk = value; }
        public RequestBean getRequest() { return request; }
@@ -51,6 +81,13 @@
        public AuthBean() {
        }
        /**
         *  认证信息
         * @param mac_key mac key
         * @param spk 产品spk
         * @param request 请求对象
         */
        public AuthBean(String mac_key, String spk, RequestBean request) {
            this.mac_key = mac_key;
            this.spk = spk;
@@ -71,16 +108,52 @@
            this.firmware_version = firmware_version;
        }
        /**
         * 设备MAC
         * @return
         */
        public String getMAC() { return mac; }
        /**
         * 设备MAC
         * @param value
         */
        public void setMAC(String value) { this.mac = value; }
        /**
         * 厂家
         * @return
         */
        public String getSupplier() { return supplier; }
        /**
         * 厂家
         * @param value
         */
        public void setSupplier(String value) { this.supplier = value; }
        /**
         * 硬件版本
         * @return
         */
        public String getHardwareModel() { return hardware_model; }
        /**
         * 硬件版本
         * @param value
         */
        public void setHardwareModel(String value) { this.hardware_model = value; }
        /**
         * 软件版本
         * @return
         */
        public String getFirmwareVersion() { return firmware_version; }
        /**
         * 软件版本
         * @param value
         */
        public void setFirmwareVersion(String value) { this.firmware_version = value; }
    }
@@ -97,46 +170,197 @@
        private String ip_gateway;
        private String dns1 = "114.114.114.114";
        private String dns2 = "8.8.8.8";
        private VersionBean[] versions;
        private String gateway_type;
        private String hw_version;
        private String fw_version;
        public String getOID() { return oid; }
        /**
         * 设备Oid
         * @param value
         */
        public void setOID(String value) { this.oid = value; }
        public String getDeviceMAC() { return device_mac; }
        /**
         * 设备Mac
         * @param value
         */
        public void setDeviceMAC(String value) { this.device_mac = value; }
        /**
         * 设备名
         * @return
         */
        public String getDeviceName() { return device_name; }
        /**
         * 设备名
         * @param value
         */
        public void setDeviceName(String value) { this.device_name = value; }
        /**
         * 设备型号
         * @return
         */
        public String getDeviceModel() { return device_model; }
        /**
         * 设备型号
         * @param value
         */
        public void setDeviceModel(String value) { this.device_model = value; }
        /**
         * 连接类型,有线还是无线
         * @return
         */
        public String getAccessMode() { return access_mode; }
        /**
         * 连接类型,有线还是无线
         * @param value
         */
        public void setAccessMode(String value) { this.access_mode = value; }
        /**
         * 设备sid
         * @return
         */
        public String getSid() { return sid; }
        /**
         * 设备sid
         * @param value
         */
        public void setSid(String value) { this.sid = value; }
        /**
         * 设备IPMAC
         * @return
         */
        public String getIPMAC() { return ip_mac; }
        /**
         * 设备IPMAC
         * @param value
         */
        public void setIPMAC(String value) { this.ip_mac = value; }
        /**
         * 设备IP地址
         * @return
         */
        public String getIPAddress() { return ip_address; }
        /**
         * 设备IP地址
         * @param value
         */
        public void setIPAddress(String value) { this.ip_address = value; }
        /**
         * 子网掩码
         * @return
         */
        public String getNetmask() { return netmask; }
        /**
         * 子网掩码
         * @param value
         */
        public void setNetmask(String value) { this.netmask = value; }
        /**
         * 网关IP
         * @return
         */
        public String getIPGateway() { return ip_gateway; }
        /**
         * 网关IP
         * @param value
         */
        public void setIPGateway(String value) { this.ip_gateway = value; }
        /**
         * DNS1
         * @return
         */
        public String getDns1() { return dns1; }
        /**
         * DNS1
         * @param value
         */
        public void setDns1(String value) { this.dns1 = value; }
        /**
         * DNS2
         * @return
         */
        public String getDns2() { return dns2; }
        /**
         * DNS2
         * @param value
         */
        public void setDns2(String value) { this.dns2 = value; }
        public VersionBean[] getVersions() { return versions; }
        public void setVersions(VersionBean[] value) { this.versions = value; }
        public VersionBean[] getVersions() {return null;  }
        public void setVersions(VersionBean[] value) {  }
        /**
         * 网关类型
         * @return
         */
        public String getGateway_type() {
            return gateway_type;
        }
        /**
         * 网关类型
         * @param gateway_type
         */
        public void setGateway_type(String gateway_type) {
            this.gateway_type = gateway_type;
        }
        /**
         * 硬件版本
         * @return
         */
        public String getHw_version() {
            return hw_version;
        }
        /**
         *硬件版本
         * @param
         */
        public void setHw_version(String hw_version) {
            this.hw_version = hw_version;
        }
        /**
         * 固件版本
         * @return
         */
        public String getFw_version() {
            return fw_version;
        }
        /**
         * 固件版本
         * @param fw_version
         */
        public void setFw_version(String fw_version) {
            this.fw_version = fw_version;
        }
    }
    public static class VersionBean implements Serializable{
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BroadcastRequest.java
New file
@@ -0,0 +1,54 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
/**
 * Created by jlchen on 11/11/21.
 *
 * /user/all/custom/gateway/broadcast
 */
public class BroadcastRequest implements Serializable {
    private String id;
    private String time_stamp;
    private AuthenticateRequest.AuthenticateDeviceInfoBean objects;//当前设备基本信息
    private String code;//
    public BroadcastRequest(String id, String time_stamp, AuthenticateRequest.AuthenticateDeviceInfoBean objects, String code) {
        this.id = id;
        this.time_stamp = time_stamp;
        this.objects = objects;
        this.code = code;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTime_stamp() {
        return time_stamp;
    }
    public void setTime_stamp(String time_stamp) {
        this.time_stamp = time_stamp;
    }
    public AuthenticateRequest.AuthenticateDeviceInfoBean getObjects() {
        return objects;
    }
    public void setObjects(AuthenticateRequest.AuthenticateDeviceInfoBean objects) {
        this.objects = objects;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/PropertyReadRequest.java
@@ -1,9 +1,12 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
/**
 * Created by Tong on 2021/10/8.
 */
public class PropertyReadRequest {
public class PropertyReadRequest implements Serializable
{
    private String sid;
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java
@@ -3,7 +3,9 @@
import android.text.TextUtils;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.SPUtils;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
@@ -23,6 +25,8 @@
    private String ipAddress;
    private boolean isLocalEncrypt;//网关是否需要加密通讯
    private GatewaySearchBean currentGateway;//当前网关
    private AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean;//当前设备基本信息
    /**
     * instance
@@ -111,11 +115,15 @@
    }
    public String getLocalSecret() {
        LogUtils.i("HDLLinkConfig","密钥是:"+localSecret);
        return localSecret;
    }
    public String getGatewayId() {
        return gatewayId;
    }
    public void setGatewayId(String gatewayId) {
        this.gatewayId=gatewayId;
    }
    public String getIpAddress() {
@@ -160,6 +168,7 @@
        return (!topicStr.contains(TopicConstant.GATEWAY_AUTH_BROADCAST) //网关广播入网指令
                && !topicStr.contains(TopicConstant.DEIVCE_AUTH_REQUEST) //入网认证
                && !topicStr.contains(TopicConstant.GATEWAY_SEARCH) //搜索网关主题
                && !topicStr.equals(TopicConstant.BROADCAST)
                && isLocalEncrypt//启用加密标志
        );
    }
@@ -174,4 +183,11 @@
        return String.format(topicStr, gatewayId);
    }
    public AuthenticateRequest.AuthenticateDeviceInfoBean getDeviceInfoBean() {
        return deviceInfoBean;
    }
    public void setDeviceInfoBean(AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean) {
        this.deviceInfoBean = deviceInfoBean;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
@@ -1,8 +1,12 @@
package com.hdl.sdk.connect.protocol;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.google.gson.internal.bind.DateTypeAdapter;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import com.hdl.sdk.common.event.EventDispatcher;
@@ -13,6 +17,7 @@
import com.hdl.sdk.socket.codec.ByteToMessageDecoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
/**
@@ -111,8 +116,9 @@
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected LinkResponse decoder(Object msg) throws Exception {
    protected synchronized LinkResponse decoder(Object msg) throws Exception {
        if (msg instanceof byte[]) {
            bytes.addAll(ByteUtils.toByteList((byte[]) msg));
            //如果多条命令打包在一条数据中,都需要处理完
@@ -154,18 +160,22 @@
                if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
                    //需要解密
                    byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
//                        byte[] bodyBytes = AESUtils.decryptAES(body,AuthenticateConfig.getInstance().getLocalSecret());
                    if (bodyBytes != null) {
                        response.setData(new String(bodyBytes, "utf-8"));
//                            LogUtils.i("TAG", "解密 主题:"+response.getTopic()+ " body: "+response.getData());
                        body = bodyBytes;
                    } else {
                        //解密失败,返回原数据
                        response.setData(new String(body, "utf-8"));
                        try {
                            LogUtils.e("解密失败,数据内容是:\r\n" + Base64.getEncoder().encodeToString(body));
                        } catch (Exception e) {
                        }
                    }
                } else {
                    response.setData(new String(body, "utf-8"));
                }
                String bodyString = new String(body, "utf-8");
                //非正常数据,返回
                if (!(bodyString.startsWith("{") || bodyString.startsWith("["))) {
                    continue;
                }
                response.setData(bodyString);
                LogUtils.i( "LinkMessageDecoder->decoder:" + response.getTopic() + "\r\n" + response.getData());
                //解析完成,topic发送一次
                EventDispatcher.getInstance().post(response.getTopic(), response);
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -359,9 +359,10 @@
     *
     * @param topic    发送数据
     * @param bodyStr  回复的主题
     * @param broadcast 是否要广播
     * @param callBack 回调
     */
    public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
    public void udpSendMsg(String topic, String bodyStr,boolean broadcast,  HDLLinkResponseCallBack callBack) {
        if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR));
@@ -378,6 +379,9 @@
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = HDLLinkConfig.getInstance().getIpAddress();
        if(broadcast) {
            ip = IpUtils.getBroadcastAddress();
        }
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
                    @Override
                    public void onSucceed(Object msg) {
@@ -399,8 +403,9 @@
     *
     * @param topic   发送数据
     * @param bodyStr 回复的主题
     * @param broadcast 是否广播
     */
    public void udpSendMsg(String topic, String bodyStr) {
    public void udpSendMsg(String topic, String bodyStr,boolean broadcast) {
        if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) {
            LogUtils.e("udpSendMsg", "参数不能为空");
            return;
@@ -410,7 +415,10 @@
            return;
        }
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = HDLLinkConfig.getInstance().getIpAddress();// IpUtils.getBroadcastAddress();
        String ip = HDLLinkConfig.getInstance().getIpAddress();
        if(broadcast) {
            ip = IpUtils.getBroadcastAddress();
        }
        HdlSocketHelper.sendUdpOne(getUdpBoot(), ip, UDP_PORT, message);
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -1,42 +1,37 @@
package com.hdl.sdk.connect.socket;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.event.EventDispatcher;
import com.hdl.sdk.common.event.EventListener;
import com.hdl.sdk.common.exception.HDLLinkCode;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.IdUtils;
import com.hdl.sdk.common.utils.IpUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.SPUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.bean.request.BroadcastRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.FunctionAttributeRequest;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
import com.hdl.sdk.connect.bean.LinkRequest;
import com.hdl.sdk.connect.bean.LinkResponse;
import com.hdl.sdk.connect.bean.request.PropertyReadRequest;
import com.hdl.sdk.connect.bean.request.PropertyUpRequest;
import com.hdl.sdk.connect.callback.BaseCallBack;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import com.hdl.sdk.connect.protocol.LinkMessageDecoder;
import com.hdl.sdk.connect.protocol.LinkMessageEncoder;
import com.hdl.sdk.socket.SocketBoot;
import com.hdl.sdk.socket.SocketOptions;
import com.hdl.sdk.socket.client.TcpClient;
import com.hdl.sdk.socket.client.UdpClient;
import com.hdl.sdk.socket.codec.MessagePipeLine;
import com.hdl.sdk.socket.listener.ConnectStatusListener;
import com.hdl.sdk.socket.listener.SendListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
@@ -63,7 +58,7 @@
        statusListener = new ConnectStatusListener() {
            @Override
            public void onConnecting() {
                broadcastRequest();
            }
            @Override
@@ -78,6 +73,31 @@
        };
    }
    /**
     * 广播自身信息给主网关
     */
    private void broadcastRequest() {
        String time = String.valueOf(System.currentTimeMillis());
        if (null == HDLLinkConfig.getInstance().getDeviceInfoBean()) {
            LogUtils.i("DeviceInfoBean为空,请设置当前对象");
            return;
        }
        BroadcastRequest request = new BroadcastRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), "200");
        HDLAuthSocket.getInstance().udpSendMsg(TopicConstant.BROADCAST, GsonConvert.getGson().toJson(request),true);
        HDLAuthSocket.getInstance().udpSendMsg(TopicConstant.BROADCAST, GsonConvert.getGson().toJson(request), true, new HDLLinkResponseCallBack() {
            @Override
            public void onSuccess(LinkResponse msg) {
                LogUtils.i("广播信息给主网关成功!");
            }
            @Override
            public void onError(HDLLinkException e) {
            }
        });
        HDLAuthSocket.getInstance().udpSendMsg(TopicConstant.BROADCAST, GsonConvert.getGson().toJson(request),true);
    }
    private static class SingletonInstance {
        private static final HDLSocket INSTANCE = new HDLSocket();
    }
@@ -86,17 +106,17 @@
        return SingletonInstance.INSTANCE;
    }
    SocketOptions options;
    private SocketOptions getTcpOptions() {
        final SocketOptions options = new SocketOptions();
        if(null!=options){
            return options;
        }
        options = new SocketOptions();
        final MessagePipeLine pipeLine = new MessagePipeLine();
        pipeLine.add(new LinkMessageDecoder());
        pipeLine.add(new LinkMessageEncoder());
        options.setHandleMessage(pipeLine);
        options.setEnabledHeartbeat(false);//是否开启心跳包发送检测
//        options.setHeartbeatTimeInterval(10*1000L);
//        options.setHeartbeatData("TCP");
//        options.setEnabledHeartbeat(true);//是否开启心跳包发送检测
        options.addConnectStatusListener(statusListener);
        return options;
    }
@@ -387,11 +407,14 @@
    public SocketBoot getTcp() throws RuntimeException {
        if (TextUtils.isEmpty(getTcpIp())) {
            LogUtils.e("请搜索网关");
            throw new RuntimeException("请搜索网关");
        }
        if (tcpBoot == null) {
        //如果没有初始化,或者网关IP更改了,就重新初始化
        if (tcpBoot == null||!getTcpOptions().getIp().equals(getTcpIp())) {
            tcpBoot = TcpClient.init(getTcpIp(), getTcpPort(), getTcpOptions());
        }
        return tcpBoot;
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -21,7 +21,7 @@
 */
public class HdlSocketHelper {
    private static final Long DEF_SEND_TIMEOUT = 1000L;
    private static final Long DEF_SEND_TIMEOUT = 500L;
    private static final int DEF_MAX_RETRY = 4;
    private static final int DEF_SEND_ONE = 1;
HDLSDK/hdl-socket/build.gradle
@@ -9,7 +9,7 @@
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 2
        versionName "1.0.2"
        versionName "1.0.5"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java
@@ -27,25 +27,19 @@
public class SocketBoot {
    private ExecutorService connectThread;
    private ScheduledExecutorService heartbeatThread;
    private ExecutorService sendThread;
    private ExecutorService receiveThread;
    private ScheduledExecutorService delayThread;
    private final IClient client;
//    public IClient getClient() {
//        return client;
//    }
    /**
     * socket是否在运行
     * tcp是否已经连接
     */
    private final AtomicBoolean isRun = new AtomicBoolean(false);
    private boolean connected=false;
    private final AtomicBoolean isOpenRetry = new AtomicBoolean(false);
    private final AtomicInteger resendCount = new AtomicInteger(0);
    public IClient getClient() {
        return client;
    }
    private final BlockingQueue<SocketRequest> mMessageQueue = new LinkedBlockingDeque<>();
@@ -53,88 +47,42 @@
    public SocketBoot(IClient client) {
        this.client = client;
        initConnectThread();
        initReceiveThread();
        initSendThread();
    }
    public ScheduledExecutorService getHeartBeat() {
        if (heartbeatThread == null) {
            heartbeatThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
        }
        return heartbeatThread;
    }
    public void connect() {
        resendCount.set(0);
        resetConnect(true);
        isOpenRetry.set(true);
    }
    public synchronized void resetConnect(boolean isFirst) {
        final int maxRetry = client.getOptions().getMaxRetry();
        if (maxRetry == 0 && resendCount.get() > 0 ||
                (maxRetry > 0 && maxRetry + 1 < resendCount.get())) {
            LogUtils.d("====", "===重连次数达到最大==");
            return;
        }
        if (!client.isConnect()) {
            if (connectThread == null) {
                connectThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
            }
            connectThread.execute(new Runnable() {
                @Override
                public void run() {
                    client.onConnectStatus(ConnectStatus.CONNECTING);
                    if (!isFirst) {
                        try {
                            resendCount.set(resendCount.get() + 1);
                            Thread.sleep(300L);
                            LogUtils.d("====", "==重连第" + resendCount + "次==");
                        } catch (Exception ignored) {
                        }
                    }
                    try {
                        client.connect();
                        isRun.set(true);
                        if (client.isConnect()) {
                            LogUtils.d("====", "====连接成功====");
                            startHeartbeat();
                            initSendThread();
                            initReceiveThread();
                            client.onConnectStatus(ConnectStatus.CONNECTED);
                            resendCount.set(0);
                        } else {
                            throw new ConnectException();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        LogUtils.d("====", "===连接失败===" + e);
                        //再判断一下有没有连接
                        if (!client.isConnect()) {
                            isRun.set(false);
                            client.onConnectStatus(ConnectStatus.DISCONNECT);
                            stopHeartbeat();
                            disconnectError();
                        }
                    }
                }
            });
    /**
     * 连接tcp,内部维护掉,可以不用开放外部,根据这个业务我特性处理好
     */
    private synchronized void connect() {
        try {
            LogUtils.i("TCP连接");
            client.onConnectStatus(ConnectStatus.CONNECTING);
            Thread.sleep(700);
            client.connect();
            connected=true;
            client.onConnectStatus(ConnectStatus.CONNECTED);
        }catch(Exception e) {
            LogUtils.e("连接异常"+e.getMessage());
        }
    }
    public void initSendThread() {
    /**
     * 初始化发送线程,只需要初始化一次
     */
    private void initSendThread() {
        if (sendThread == null) {
            sendThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
        }
        sendThread.execute(new Runnable() {
            @Override
            public void run() {
                while (isRun.get()) {
                    if (client.isConnect()) {
            sendThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            SocketRequest socketRequest = mMessageQueue.take();
                            final String sendStr = new String(socketRequest.getData(), 0, socketRequest.getData().length);
                            LogUtils.i("发送数据:"+sendStr);
//                            final String sendStr = new String(socketRequest.getData(), 0, socketRequest.getData().length);
//                            LogUtils.i("发送数据:" + sendStr);
                            final String action = socketRequest.getAction();
                            try {
                                client.sendMsg(socketRequest.getData());
@@ -145,33 +93,22 @@
                                    }
                                }
                            } catch (Exception e) {
                                connected = false;
                                LogUtils.e("发送失败:" + e.getMessage());
                                if (!TextUtils.isEmpty(action)) {
                                    SendListener sendListener = sendMap.get(action);
                                    if (sendListener != null) {
                                        sendListener.onError();
                                    }
                                }
                                stopHeartbeat();
                                if (sendThread != null) {
                                    sendThread.shutdownNow();
                                }
                                if (isRun.get()) {
                                    disconnectError();
                                }
                            }
                        } catch (InterruptedException ignored) {
                        } catch (Exception e) {
                        }
                    }
                }
                LogUtils.d("=====", "==发送线程关闭==");
            }
        });
            });
        }
    }
    /**
@@ -183,151 +120,94 @@
            receiveThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (isRun.get()) {
                        if (client.isConnect()) {
                            try {
                    while (true) {
                        try {
                            if (connected) {
                                //读取数据
                                client.onHandleResponse();
                            } catch (Exception e) {
                                e.printStackTrace();
                                disconnectError();
                            } else {
                                try {
                                    Thread.sleep(1000);
                                } catch (Exception ee) {
                                }
                            }
                        } catch (Exception e) {
                            connected = false;
                            LogUtils.e("接收数据线程异常" + e.getMessage());
                        }
                    }
                    LogUtils.i("Socket 线程退出接收数据");
                }
            });
        }
    }
    /**
     * 初始化重新连接线程
     */
    private void initConnectThread() {
        if (connectThread == null) {
            connectThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
            //一定时间检测一次连接情况,没有连接就执行连接,连接统一由这里维护
            connectThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            if (!connected) {
                                reconect();
                            }
                            Thread.sleep(10*1000);
                        } catch (Exception e) {
    public void startHeartbeat() {
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
        }
        if (client.getOptions() == null || client.getOptions().getHeartbeatTimeInterval() <= 0 || !client.getOptions().isEnabledHeartbeat()) {
            return;
        }
        getHeartBeat().scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                if (isRun.get()) {
//                    LogUtils.d("====", "===发送心跳包===");
                    if (client.getOptions() != null) {
                        final byte[] heartBeat = client.getOptions().getHeartbeatData();
                        if (heartBeat != null) {
                            sendMsg(heartBeat, false, null);
                        } else {
                            sendMsg(new byte[0], false, null);
                        }
                    }
                }
            }
        }, client.getOptions().getHeartbeatTimeInterval(), client.getOptions().getHeartbeatTimeInterval(), TimeUnit.MILLISECONDS);
    }
    public void stopHeartbeat() {
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
            });
        }
    }
    /**
     * 重新连接
     */
    private void reconect() {
        disconnect();
        connect();
    }
    /**
     * 发送无需回调
     * @param msg 发送的数据
     */
    public void sendMsg(byte[] msg) {
        sendMsg(msg, true, null);
        sendMsg(msg, null);
    }
    public void sendMsg(byte[] msg, SendListener listener) {
        sendMsg(msg, true, listener);
    }
    /**
     * @param listener 一般情况无需监听
     */
    private void sendMsg(byte[] msg, boolean isRefreshRetry, SendListener listener) {
        if (isRefreshRetry) {
            //重置连接次数
            resendCount.set(0);
        }
    public void sendMsg(byte[] msg, SendListener listener) {
        try {
            SocketRequest request = new SocketRequest(msg);
            if (listener != null && !TextUtils.isEmpty(request.getAction())) {
                sendMap.put(request.getAction(), listener);
            }
            mMessageQueue.put(request);
        } catch (InterruptedException ignored) {
        } catch (Exception e) {
        }
        if (!client.isConnect()) {
            resetConnect(false);
        }
    }
    /**
     * 发生错误,重连
     * 关闭连接
     */
    private void disconnectError() {
        disconnect();
        isRun.set(false);
        if (isOpenRetry.get()) {
            if (delayThread != null) {
                delayThread.shutdownNow();
            }
            delayThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
            delayThread.schedule(new Runnable() {
                @Override
                public void run() {
                    if (!client.isConnect() && isOpenRetry.get()) {
                        resetConnect(false);
                    }
                }
            }, 3000, TimeUnit.MILLISECONDS);
        }
    }
    private synchronized void disconnect() {
        if (client.isConnect()) {
        try {
            client.disconnect();
            //断开连接
            client.onConnectStatus(ConnectStatus.DISCONNECT);
        }
    }
        } catch (Exception e) {
    public synchronized void close() {
        isOpenRetry.set(false);
        isRun.set(false);
        if (connectThread != null) {
            connectThread.shutdownNow();
            connectThread = null;
        }
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
        }
        if (sendThread != null) {
            sendThread.shutdownNow();
            sendThread = null;
        }
        if (receiveThread != null) {
            receiveThread.shutdownNow();
            receiveThread = null;
        }
        sendMap.clear();
        client.disconnect();
        mMessageQueue.clear();
    }
    public synchronized void release() {
        close();
        if (client != null && client.getOptions() != null) {
            client.getOptions().clearConnectStatusListener();
        }
    }
    public boolean isConnect() {
        return client.isConnect();
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java
@@ -14,17 +14,9 @@
 */
public class SocketOptions {
    //设置读取缓存
    private int readMaxBufferSize = 512;
    //发送心跳包
    private boolean isEnabledHeartbeat = true;
    //心跳包
    private byte[] heartbeatData;
    //心跳包时间间隔
    private long heartbeatTimeInterval = 300L;
    //发送目标地址IP
    private String ip="";
    private int port;
    //处理数据
    private IHandleMessage handleMessage;
@@ -32,18 +24,22 @@
    //监听状态
    private List<ConnectStatusListener> mConnectStatusListener;
    //最大重连次数,小于0无限次数,等于0不重连
    private int maxRetry = -1;
    private boolean isTcpNoDelay;
    private boolean isReuseAddress;
    //保持活动状态
    private boolean isKeepAlive;
    private boolean isOOBInline;
    private int sendBufferSize;
    private int receiveBufferSize;
    private int soTimeout;
    private boolean soLinger;
    public String getIp() {
        return ip;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public IHandleMessage getHandleMessage() {
        return handleMessage;
@@ -51,38 +47,6 @@
    public void setHandleMessage(IHandleMessage handleMessage) {
        this.handleMessage = handleMessage;
    }
    public boolean isEnabledHeartbeat() {
        return isEnabledHeartbeat;
    }
    public void setEnabledHeartbeat(boolean enabledHeartbeat) {
        isEnabledHeartbeat = enabledHeartbeat;
    }
    public byte[] getHeartbeatData() {
        return heartbeatData;
    }
    public void setHeartbeatData(byte[] heartbeatData) {
        this.heartbeatData = heartbeatData;
    }
    public void setHeartbeatData(String heartbeatData) {
        try {
            this.heartbeatData = heartbeatData.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    public long getHeartbeatTimeInterval() {
        return heartbeatTimeInterval;
    }
    public void setHeartbeatTimeInterval(long heartbeatTimeInterval) {
        this.heartbeatTimeInterval = heartbeatTimeInterval;
    }
    public void clearConnectStatusListener() {
@@ -104,26 +68,8 @@
        }
    }
    public List<ConnectStatusListener> getConnectStatusListener() {
        return mConnectStatusListener;
    }
    public int getMaxRetry() {
        return maxRetry;
    }
    public void setMaxRetry(int maxRetry) {
        this.maxRetry = maxRetry;
    }
    public int getReadMaxBufferSize() {
        return readMaxBufferSize;
    }
    public void setReadMaxBufferSize(int readMaxBufferSize) {
        this.readMaxBufferSize = readMaxBufferSize;
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java
@@ -12,11 +12,6 @@
    void disconnect();
    /**
     * 是否已经连接
     */
    boolean isConnect();
    SocketOptions getOptions();
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java
@@ -3,6 +3,7 @@
import com.hdl.sdk.common.utils.ByteUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.socket.SocketBoot;
import com.hdl.sdk.socket.SocketOptions;
@@ -15,6 +16,8 @@
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
@@ -31,12 +34,32 @@
    private Socket mSocket;
    private byte[] readBuffer;
    private final static List<TcpClient> tcpClientList = new ArrayList();
    /**
     * 从连接池中找出当前IP及端口的连接客户端
     * @param ipAdderss 连接IP地址
     * @param port 连接端口
     * @return
     */
    public static TcpClient getTcpClientByIP(String ipAdderss,int port) {
        for(TcpClient tcpClient:tcpClientList){
            if(tcpClient.ip.equals(ipAdderss)&&tcpClient.port==port)
            {
                return tcpClient;
            }
        }
        return  null;
    }
    private byte[] readBuffer = new byte[4*1024];
    private TcpClient(String ip, int port, SocketOptions socketOptions) {
        this.socketOptions = socketOptions;
        this.ip = ip;
        this.port = port;
        socketOptions.setIp(ip);
        socketOptions.setPort(port);
    }
    public static SocketBoot init(String ip, int port, SocketOptions options) {
@@ -46,14 +69,19 @@
    @Override
    public void connect() throws Exception {
        mSocket = getSocket();
        SocketOptions options = getOptions();
        mSocket.connect(new InetSocketAddress(ip, port));
//        SocketOptions options = getOptions();
        mSocket.connect(new InetSocketAddress(ip, port), 3 * 1000);
        mSocket.setTcpNoDelay(true);
        mSocket.setReuseAddress(true);
        mSocket.setKeepAlive(true);
        readBuffer = new byte[options.getReadMaxBufferSize()];
        mSocket.setSoTimeout(20 * 1000);
        tcpClientList.add(this);
    }
    @Override
@@ -68,16 +96,6 @@
    }
    @Override
    public boolean isConnect() {
        if (mSocket == null) {
            return false;
        }
        return mSocket.isConnected() && !mSocket.isClosed();
    }
    @Override
    public synchronized SocketOptions getOptions() {
        if (socketOptions == null) {
            socketOptions = new SocketOptions();
@@ -89,12 +107,17 @@
    public void onHandleResponse() throws Exception {
        final InputStream stream = getInputStream();
        if (stream != null && getOptions() != null) {
            int len=0;
            while ( (len=getInputStream().read(readBuffer)) != -1) {
            while ( true) {
                int len=getInputStream().read(readBuffer);
                if(len<=0){
                    throw  new Exception("接收异常,接收数据长度len="+len);
                }
                IHandleMessage handleMessage = getOptions().getHandleMessage();
                if (handleMessage != null) {
                    byte []bytes = new byte[len];
                    System.arraycopy(readBuffer,0,bytes,0,len);
                    LogUtils.i("收到TCP数据",new String(bytes));
                    //完整的数据才回调
                    handleMessage.read(bytes);
                }
@@ -106,14 +129,10 @@
    public void sendMsg(byte[] msg) throws Exception {
        final OutputStream outputStream = getOutStream();
        if (outputStream != null && getOptions() != null) {
            try {
                IHandleMessage handleMessage = getOptions().getHandleMessage();
                handleMessage.write(handleMessage.write(msg));
                getOutStream().write(msg);
            } finally {
                outputStream.write(msg);
                outputStream.flush();
            }
        }
    }
HDLSDK_DEMO.zip
Binary files differ
HDLSDK_DEMO/app/libs/hdl-common-V1.0.2.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-common-V1.0.3.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.2.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.3.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.2.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.3.aar
Binary files differ