3个文件已添加
16个文件已修改
1400 ■■■■■ 已修改文件
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 166 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/exception/HDLLinkCode.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java 224 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java 149 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketPool.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IUdpClient.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/udp/UdpSocketBoot.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/udp/UdpSocketOptions.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-common-V1.0.1.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.1.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.1.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 111 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -37,6 +37,7 @@
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
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.socket.HDLAuthSocket;
import com.hdl.sdk.connect.socket.HDLSocket;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
@@ -105,6 +106,8 @@
        beans.add(new DemoBean("设备功能列表"));
        beans.add(new DemoBean("UDP发送"));
        beans.add(new DemoBean("TCP发送"));
        beans.add(new DemoBean("UDP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("TCP发送,监听主题回复,带重发带回调"));
        demoAdapter = new DemoAdapter(beans);
        rv.setAdapter(demoAdapter);
@@ -128,12 +131,12 @@
                        searchGatewayBroadcast();
                        break;
                    case 2:
                       //获取功能列表
                        //获取功能列表
                        getFunctionList();
                        break;
                    case 3:
                        //功能属性读取
                       getFunctionAttribute();
                        getFunctionAttribute();
                        break;
                    case 4:
                        //设备控制
@@ -163,11 +166,18 @@
                        //TCP发送
                        tcpSend();
                        break;
                    case 11:
                        //UDP发送,监听主题回复,带重发带回调
                        udpSendWithCallback();
                        break;
                    case 12:
                        //TCP发送,监听主题回复,带重发带回调
                        tcpSendWithCallback();
                        break;
                }
            }
        });
    }
    public void showToast(String text) {
@@ -177,9 +187,9 @@
    /**
     * 检测是否认证过
     */
    void checkIfCertified(){
    void checkIfCertified() {
        boolean isCertified = HDLLink.getInstance().checkIfCertified();
        String mes = isCertified?"已经认证过":"未认证";
        String mes = isCertified ? "已经认证过" : "未认证";
        showToast(mes);
        tv.setText(mes);
    }
@@ -187,11 +197,11 @@
    /**
     * 注册所有主题数据的监听
     */
    void registerAllTopicsListener(){
    void registerAllTopicsListener() {
        allTopicsListener = new EventListener() {
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse)msg;
                LinkResponse response = (LinkResponse) msg;
            }
        };
        HDLLink.getInstance().registerAllTopicsListener(allTopicsListener);
@@ -199,20 +209,21 @@
    /**
     * 处理收到的主题
     *
     * @param response
     */
    private void handleLinkResponse(LinkResponse response){
    private void handleLinkResponse(LinkResponse response) {
        //网关搜索回复
        if(response.getTopic().contains("/user/all/custom/gateway/search_reply")){
        if (response.getTopic().contains("/user/all/custom/gateway/search_reply")) {
            String data = response.getData();
            if (!TextUtils.isEmpty(data)) {
                Log.i("handleLinkResponse", "data:"+data);
                Log.i("handleLinkResponse", "data:" + data);
                final BaseLocalResponse<GatewaySearchBean> bean = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() {
                }.getType());
                GatewaySearchBean searchBean = bean.getObjects();
                Log.i("handleLinkResponse", "GatewaySearchBean: "+searchBean.getGatewayId());
                Log.i("handleLinkResponse", "GatewaySearchBean: " + searchBean.getGatewayId());
            }
        }else{
        } else {
            //其它主题
        }
@@ -228,7 +239,6 @@
                }.getType());
                searchBean = response.getObjects();
            }
        }
        return searchBean;
    }
@@ -236,20 +246,27 @@
    /**
     * 移除所有主题数据的监听
     */
    void removeAllTopicsListener(){
    void removeAllTopicsListener() {
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest(){
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
        //认证提交参数准备
        String spkStr = "screen.mirror";//产品spk
        String macStr = "AA000000000000AC";//设备唯一MAC地址
        String secret = "ee62124c151b737c";//通过spk和mac提交云端认证后分配的secret
        //测试服务
        String spkStr = "ir.module";//产品spk
        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
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
@@ -323,7 +340,7 @@
     * 如果已经认证后,搜索指定网关是否在线
     * 广播搜索认证过的网关是否在线
     */
    void searchGatewayBroadcast(){
    void searchGatewayBroadcast() {
        tv.setText("搜索网关中...");
        HDLLink.getInstance().searchGatewayBroadcast(new HDLAuthSocket.SearchGatewayCallBack() {
            @Override
@@ -331,10 +348,11 @@
                tv.setText("网关不在线");
                responseTv.setText(e.getMsg());
            }
            @Override
            public void onSuccess(GatewaySearchBean gatewaySearchBean) {
                tv.setText("网关在线");
                responseTv.setText("搜索成功 网关id:"+gatewaySearchBean.getGatewayId());
                responseTv.setText("搜索成功 网关id:" + gatewaySearchBean.getGatewayId());
//                                LogUtils.i("TAG", "onSuccess: 搜索成功:"+gatewaySearchBean.getGatewayId());
            }
        });
@@ -343,7 +361,7 @@
    /**
     * 获取功能列表
     */
    void getFunctionList(){
    void getFunctionList() {
        tv.setText("获取功能列表中...");
        responseTv.setText("");
        HDLLink.getInstance().getFunctionList(new HDLLinkCallBack() {
@@ -364,7 +382,7 @@
     * 功能属性读取
     * 支持批量读取
     */
    void getFunctionAttribute(){
    void getFunctionAttribute() {
        tv.setText("功能属性读取");
        List<String> sids = new ArrayList<>();
        sids.add(testLightSid);
@@ -385,7 +403,7 @@
     * 读取设备状态
     * 支持批量读取
     */
    void propertyRead(){
    void propertyRead() {
        tv.setText("读取状态中...");
        List<String> list = new ArrayList<>();
        list.add(testLightSid);//要读取设备的sid
@@ -395,6 +413,7 @@
                tv.setText("读取成功");
                responseTv.setText(data);
            }
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("读取失败");
@@ -407,14 +426,14 @@
     * 控制失败
     * 回复响应code为200 代表执行成功
     */
    void controlDecide(){
    void controlDecide() {
        tv.setText("控制设备");
        isOn = !isOn;
        List<DeviceControlRequest> requestList = new ArrayList<>();
        DeviceControlRequest request = new DeviceControlRequest();
        request.setSid(testLightSid);
        List<DeviceControlRequest.StatusBean>  statusBeanList= new ArrayList<>();
        DeviceControlRequest.StatusBean bean =  new DeviceControlRequest.StatusBean();
        List<DeviceControlRequest.StatusBean> statusBeanList = new ArrayList<>();
        DeviceControlRequest.StatusBean bean = new DeviceControlRequest.StatusBean();
        bean.setKey("on_off");
        bean.setValue(isOn ? "on" : "off");
        statusBeanList.add(bean);
@@ -436,7 +455,7 @@
    /**
     * 获取场景列表
     */
    void getSceneList(){
    void getSceneList() {
        tv.setText("读取场景列表");
        HDLLink.getInstance().getSceneList(new HDLLinkCallBack() {
            @Override
@@ -453,21 +472,22 @@
    //场景列表
    // {"id":"8a5eaa143ce943b987b577df5a66759b","time_stamp":"1637040217235","objects":[{"sid":"04010560D2C7170A0A0100000000","name":"回家模式","status":"off","group":"255","delay":"0","modify_time":"1634871490"},{"sid":"04010560D2C76E0A0A0100010000","name":"离家模式","status":"off","group":"255","delay":"0","modify_time":"1634785823"}]}
    /**
     * 控制场景
     * 执行成功的话 响应code为200
     */
    void controlScene(){
    void controlScene() {
        tv.setText("场景控制");
        //控制场景sid列表,支持批量控制
        List<String> sids = new ArrayList<>();
        isOn = !isOn;
        if(isOn){
        if (isOn) {
            sids.add("04010560D2C7170A0A0100000000");
        }else{
        } else {
            sids.add("04010560D2C76E0A0A0100010000");
        }
        HDLLink.getInstance().controlScene(sids,new HDLLinkCallBack() {
        HDLLink.getInstance().controlScene(sids, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
@@ -481,7 +501,7 @@
    }
    void startDevicesListActivity(){
    void startDevicesListActivity() {
        Intent intent = new Intent(this, DevicesListActivity.class);
        startActivity(intent);
    }
@@ -490,21 +510,83 @@
     * TCP发送 只发一次,不监听回复,不重发
     */
    private void tcpSend() {
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().tcpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString());
        tv.setText("TCP发送 只发一次,不监听回复,不重发");
        String propertyDownTopic = String.format(TopicConstant.PROPERTY_DOWN, HDLLinkConfig.getInstance().getGatewayId());
        String bodyStr = getPropertyDownBodyStr();
        HDLLink.getInstance().tcpSendMsg(propertyDownTopic, bodyStr);
    }
    /**
     * 只发一次,不监听回复,不重发
     * UDP只发一次,不监听回复,不重发
     */
    private void udpSend() {
        tv.setText("UDP发送 只发一次,不监听回复,不重发");
        String propertyDownTopic = String.format(TopicConstant.PROPERTY_DOWN, HDLLinkConfig.getInstance().getGatewayId());
        String bodyStr = getPropertyDownBodyStr();
        HDLLink.getInstance().udpSendMsg(propertyDownTopic, bodyStr);
    }
    private String getPropertyDownBodyStr() {
        isOn = !isOn;
        List<DeviceControlRequest> requestList = new ArrayList<>();
        DeviceControlRequest request = new DeviceControlRequest();
        request.setSid(testLightSid);
        List<DeviceControlRequest.StatusBean> statusBeanList = new ArrayList<>();
        DeviceControlRequest.StatusBean bean = new DeviceControlRequest.StatusBean();
        bean.setKey("on_off");
        bean.setValue(isOn ? "on" : "off");
        statusBeanList.add(bean);
        request.setStatus(statusBeanList);
        requestList.add(request);
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().udpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString());
        final BaseLocalResponse<List<DeviceControlRequest>> data = new BaseLocalResponse<>();
        data.setId(IdUtils.getUUId());
        data.setTime_stamp(time);
        data.setObjects(requestList);
        return GsonConvert.getGson().toJson(data);
    }
    /**
     * UDP发送,监听主题回复,带重发带回调
     */
    private void udpSendWithCallback() {
        tv.setText("UDP发送,监听主题回复,带重发带回调");
        String propertyDownTopic = String.format(TopicConstant.PROPERTY_DOWN, HDLLinkConfig.getInstance().getGatewayId());
        String bodyStr = getPropertyDownBodyStr();
        HDLLink.getInstance().udpSendMsg(propertyDownTopic, bodyStr, new HDLLinkResponseCallBack() {
            @Override
            public void onSuccess(LinkResponse msg) {
                Log.i("udpSendWithCallback", "udpSendWithCallback");
                responseTv.setText(GsonConvert.getGson().toJson(msg));
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * TCP发送,监听主题回复,带重发带回调
     */
    private void tcpSendWithCallback() {
        tv.setText("TCP发送,监听主题回复,带重发带回调");
        String propertyDownTopic = String.format(TopicConstant.PROPERTY_DOWN, HDLLinkConfig.getInstance().getGatewayId());
        String bodyStr = getPropertyDownBodyStr();
        HDLLink.getInstance().tcpSendMsg(propertyDownTopic, bodyStr, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                Log.i("tcpSendWithCallback", "tcpSendWithCallback");
                responseTv.setText(msg);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
}
HDLSDK/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java
@@ -1,6 +1,7 @@
package com.hdl.hdlsdk.device;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -101,14 +102,17 @@
        requestList.add(request);
        String time = String.valueOf(System.currentTimeMillis());
        final BaseLocalResponse<List<DeviceControlRequest>> data = new BaseLocalResponse<>();
        data.setId(IdUtils.getUUId());
        data.setTime_stamp(time);
        data.setObjects(requestList);
        HDLLink.getInstance().propertyDown(requestList, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String data) {
                Log.i("propertyDown",data);
            }
        String topic = String.format(TopicConstant.PROPERTY_DOWN, HDLLinkConfig.getInstance().getGatewayId());
            @Override
            public void onError(HDLLinkException e) {
                Log.e("propertyDown", "ERROR :"+ e.getMsg());
            }
        });
        HDLLink.getInstance().tcpSendMsg(topic, GsonConvert.getGson().toJson(data));
//        HDLLink.getInstance().udpSendMsg(topic, GsonConvert.getGson().toJson(data));
    }
}
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/exception/HDLLinkCode.java
@@ -15,6 +15,7 @@
    HDL_UNAUTHORIZED_ERROR(-2005,"未认证,请先认证"),
    HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED(-2006,"认证失败,网关未注册到云端"),
    HDL_SEARCH_GATEWAY_TIMEOUT_ERROR(-2007,"搜索网关失败,超时"),
    HDL_AUTH_MAC_KEY_ERROR_(-2008,"认证失败,该MAC对应的设备密钥不存在"),
    HDL_GET_DEVICE_LIST_ERROR(-2100,"获取设备列表失败"),
    HDL_GET_FUNCTION_LIST_ERROR(-2101,"获取功能列表失败"),
    HDL_GET_FUNCTION_PROPERTIES_ERROR(-2102,"获取功能属性失败"),
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java
@@ -87,6 +87,13 @@
    }
    /**
     * 重新保存
     */
    public void reSaveConfig() {
        this.saveConfig(this.localSecret, this.gatewayId, this.ipAddress);
    }
    /**
     * 检测是否已经认证过
     *
     * @return
@@ -114,6 +121,9 @@
    public String getIpAddress() {
        return ipAddress;
    }
    public void setIpAddress(String ipAddress){
        this.ipAddress = ipAddress;
    }
    public boolean isLocalEncrypt() {
        return isLocalEncrypt;
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -1,6 +1,5 @@
package com.hdl.sdk.connect.socket;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.text.TextUtils;
import com.google.gson.Gson;
@@ -12,6 +11,7 @@
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.response.AuthenticateResponse;
import com.hdl.sdk.connect.bean.response.NetworkAccessBroadcastResponse;
import com.hdl.sdk.connect.callback.BaseCallBack;
@@ -30,15 +30,13 @@
import com.hdl.sdk.connect.bean.LinkResponse;
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.UdpClient;
import com.hdl.sdk.socket.codec.MessagePipeLine;
import com.hdl.sdk.socket.listener.SendListener;
import com.hdl.sdk.socket.udp.UdpSocketBoot;
import com.hdl.sdk.socket.udp.UdpSocketOptions;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -47,7 +45,7 @@
/**
 * Created by jlchen on 11/11/21.
 *
 * @Description : HDLAuthSocket
 * @Description : HDLAuthSocket 由于前期已经命名好,不做更改,可用作Udp服务端使用
 */
public class HDLAuthSocket {
    private static final String TAG = "HDLAuth";
@@ -55,7 +53,10 @@
     * udp默认端口
     */
    private static final int UDP_PORT = 8585;
    private static SocketBoot updBoot;
    /**
     * 因为考虑到使用一个端口,要支持接收多网关的数据,所以只允许使用一个
     */
    private static UdpSocketBoot udpSocketBoot;
    //    private EventListener authEvent;
    //搜索网关
    private EventListener searchGatewayEvent;
@@ -70,6 +71,7 @@
    private volatile static HDLAuthSocket instance;
    private HDLAuthSocket() {
        initListenerGatewayEvent();
        initSearchGatewayEvent();
    }
@@ -93,24 +95,32 @@
        return instance;
    }
    private SocketOptions getUdpOptions() {
        final SocketOptions options = new SocketOptions();
    private UdpSocketOptions getUdpOptions() {
        final UdpSocketOptions options = new UdpSocketOptions();
        final MessagePipeLine pipeLine = new MessagePipeLine();
        pipeLine.add(new LinkMessageDecoder());
        pipeLine.add(new LinkMessageEncoder());
        options.setHandleMessage(pipeLine);
        options.setHeartbeatTimeInterval(10*1000L);
        options.setHeartbeatData("UDP");
        options.setEnabledHeartbeat(true);//是否开启心跳包发送检测
        return options;
    }
    private SocketBoot getUdpBoot(String ip) {
        if (updBoot == null) {
            updBoot = UdpClient.init(ip, UDP_PORT, getUdpOptions());
            updBoot.connect();
    /**
     * 获取当前udp对象,如果不存在就创建
     *
     * @return 返回当前对象
     */
    private UdpSocketBoot getUdpBoot() {
        try {
            if (udpSocketBoot == null) {
                udpSocketBoot = UdpClient.init(UDP_PORT, getUdpOptions());
                udpSocketBoot.bind();
            }
        } catch (Exception e) {
            return null;
        }
        return updBoot;
        return udpSocketBoot;
    }
    /**
@@ -122,7 +132,7 @@
    public void startAuthenticateRequest(AuthenticateRequest request, HDLLinkCallBack callBack) {
        HDLLinkConfig.getInstance().clearConfig();
        //1.启动Socket 开启监听
        getUdpBoot(IpUtils.getBroadcastAddress());
        getUdpBoot();
        //2.构建监听Listener
//        authEvent =
        //3.监听网关广播的入网指令
@@ -168,30 +178,39 @@
        String requestStr = gs.toJson(request);
        LinkRequest message = new LinkRequest(topic, requestStr);
        HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() {
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
            @Override
            public void onSucceed(Object msg) {
                if (callBack == null) return;
                try {
                    AuthenticateResponse bean = getAuthenticateResponseBean(msg);
                    if (bean != null) {
                        String localSecret = "";
                        String gatewayId = "";
                        String ipAddress = "";
                        if(bean.getAuth() != null) {
                            localSecret = bean.getAuth().getLocalSecret();
                        }
                        if(bean.getObjects() != null){
                             gatewayId = bean.getObjects().getGatewayID();
                             ipAddress = bean.getObjects().getIPAddress();
                        }
                        //判断网关是否已经注册到云端
                        if (TextUtils.isEmpty(localSecret) || TextUtils.isEmpty(gatewayId)) {
                            //认证失败,网关未注册到云端
                            callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED));
                        } else {
                            HDLLinkConfig.getInstance().saveConfig(localSecret, gatewayId, ipAddress);
                            callBack.onSuccess("认证成功");
                        if (bean.getCode().equals("200")) {
                            String localSecret = "";
                            String gatewayId = "";
                            String ipAddress = "";
                            if (bean.getAuth() != null) {
                                localSecret = bean.getAuth().getLocalSecret();
                            }
                            if (bean.getObjects() != null) {
                                gatewayId = bean.getObjects().getGatewayID();
                                ipAddress = bean.getObjects().getIPAddress();
                            }
                            //判断网关是否已经注册到云端
                            if (TextUtils.isEmpty(localSecret) || TextUtils.isEmpty(gatewayId)) {
                                //认证失败,网关未注册到云端
                                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED));
                            } else {
                                HDLLinkConfig.getInstance().saveConfig(localSecret, gatewayId, ipAddress);
                                callBack.onSuccess("认证成功");
                            }
                        } else if (bean.getCode().equals("14013")){
                            //认证失败,该MAC对应的设备密钥不存在
                            callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_MAC_KEY_ERROR_));
                        } else{
                            //认证失败,错误码:
                            LogUtils.e("认证失败,错误码:" + bean.getCode());
                            callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR));
                        }
                    } else {
                        callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR));
@@ -284,7 +303,7 @@
     * @param callBack 回调
     */
    public void searchGatewayMulticast(SearchGatewayCallBack callBack) {
        searchGateway(HDLLinkConfig.getInstance().getGatewayId(), UDP_GROUP_IP, callBack);
        searchGateway(HDLLinkConfig.getInstance().getGatewayId(), UDP_GROUP_IP, UDP_PORT, callBack);
    }
    /**
@@ -293,8 +312,14 @@
     * @param callBack 回调
     */
    public void searchGatewayBroadcast(SearchGatewayCallBack callBack) {
        if (!HDLLinkConfig.getInstance().checkIfCertified()) {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_UNAUTHORIZED_ERROR));
            }
            return;
        }
        String ip = IpUtils.getBroadcastAddress();
        searchGateway(HDLLinkConfig.getInstance().getGatewayId(), ip, callBack);
        searchGateway(HDLLinkConfig.getInstance().getGatewayId(), ip, UDP_PORT, callBack);
    }
@@ -312,7 +337,7 @@
                GsonConvert.getGson().toJson(data));
        String ip = IpUtils.getBroadcastAddress();
        HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() {
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
            @Override
            public void onSucceed(Object msg) {
                if (callBack == null) return;
@@ -343,9 +368,17 @@
            }
            return;
        }
        if (!HDLLinkConfig.getInstance().checkIfCertified()) {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_UNAUTHORIZED_ERROR));
            }
            return;
        }
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = IpUtils.getBroadcastAddress();
        HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() {
        String ip = HDLLinkConfig.getInstance().getIpAddress();
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
                    @Override
                    public void onSucceed(Object msg) {
                        if (callBack == null) return;
@@ -372,9 +405,13 @@
            LogUtils.e("udpSendMsg", "参数不能为空");
            return;
        }
        if (!HDLLinkConfig.getInstance().checkIfCertified()) {
            LogUtils.e("udpSendMsg", "未认证,请先认证");
            return;
        }
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = IpUtils.getBroadcastAddress();
        getUdpBoot(ip).sendMsg(message.getSendBytes());
        String ip = HDLLinkConfig.getInstance().getIpAddress();// IpUtils.getBroadcastAddress();
        HdlSocketHelper.sendUdpOne(getUdpBoot(), ip, UDP_PORT, message);
    }
    private GatewaySearchBean getGatewaySearchBean(Object msg) {
@@ -433,7 +470,7 @@
    private SearchGatewayCallBack mSearchGatewayCallBack;
    private void initSearchGatewayEvent() {
        LogUtils.i("搜索网关--", "initSearchGatewayEvent");
        LogUtils.i("搜索网关", "initSearchGatewayEvent");
        searchGatewayEvent = new EventListener() {
            @Override
            public void onMessage(Object msg) {
@@ -441,7 +478,6 @@
                    if (msg instanceof LinkResponse) {
                        LinkResponse linkResponse = (LinkResponse) msg;
                        String data = linkResponse.getData();
                        LogUtils.i("搜索到网关->" + data);
                        if (!TextUtils.isEmpty(data)) {
                            final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() {
                            }.getType());
@@ -467,14 +503,49 @@
        };
    }
    private void initListenerGatewayEvent() {
        LogUtils.i("初始化永久监听网关广播事件,不用移除此事件");
        EventListener gatewayEvent = new EventListener() {
            @Override
            public void onMessage(Object msg) {
                try {
                    if (msg instanceof LinkResponse) {
                        LinkResponse linkResponse = (LinkResponse) msg;
                        String data = linkResponse.getData();
                        LogUtils.i("接收到网关信息:" + data);
                        if (!TextUtils.isEmpty(data)) {
                            final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() {
                            }.getType());
                            GatewaySearchBean gateway = response.getObjects();
                            if (gateway != null && !TextUtils.isEmpty(gateway.getGatewayId())) {
                                //主网关并且是当前绑定的网关
                                if ("true".equals(gateway.getMaster().toLowerCase()) && gateway.getGatewayId().equals(HDLLinkConfig.getInstance().getGatewayId())) {
                                    HDLLinkConfig.getInstance().setCurrentGateway(gateway);//设置当前网关
                                    HDLLinkConfig.getInstance().setLocalEncrypt(gateway.isLocalEncrypt());//设置是否加密
                                    HDLLinkConfig.getInstance().setIpAddress(gateway.getIp_address());
                                    //更新当前网关的信息
                                    HDLLinkConfig.getInstance().reSaveConfig();
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                }
            }
        };
        EventDispatcher.getInstance().registerIo(TopicConstant.GATEWAY_SEARCH_REPLY, gatewayEvent);
    }
    /**
     * 搜索指定网关是否在线,搜索到则返回指定的网关对象
     *
     * @param gatewayId 网关id
     * @param ip        接收目标的ip地址
     * @param ipAddress 目标的IP地址
     * @param port      目标的端口
     * @param callBack  回调
     */
    public void searchGateway(String gatewayId, String ip, SearchGatewayCallBack callBack) {
    public void searchGateway(String gatewayId, String ipAddress, int port, SearchGatewayCallBack callBack) {
        this.searchGatewayId = gatewayId;
        this.mSearchGatewayCallBack = callBack;
        //重置参数
@@ -495,8 +566,8 @@
                    try {
                        //搜索网关
                        searchGatewayCount.set(searchGatewayCount.get() + 1);
                        LogUtils.i("搜索网关--", "搜索网关第" + searchGatewayCount.get() + "次");
                        getUdpBoot(ip).sendMsg(message.getSendBytes());
                        LogUtils.i("搜索网关", "搜索网关第" + searchGatewayCount.get() + "次");
                        getUdpBoot().sendMsg(ipAddress, port, message.getSendBytes());
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
@@ -506,18 +577,18 @@
                if (!isSearchGatewaySuccess.get()) {
                    //搜索10次,指定网关都没回复,回调超时
                    callBackSearchGatewayTimeout();
                    LogUtils.e("搜索网关--", "搜索10次,指定网关都没回复,回调超时");
                    LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时");
                }
            }
        }).start();
    }
    /**
     * 注册搜索网关监听
     */
    private void registerSearchGatewayEvent() {
        LogUtils.i("搜索网关--", "注册搜索网关监听");
        LogUtils.i("搜索网关", "注册搜索网关监听");
        EventDispatcher.getInstance().registerIo(TopicConstant.GATEWAY_SEARCH_REPLY, searchGatewayEvent);
    }
@@ -525,7 +596,7 @@
     * 移除搜索网关监听
     */
    private void removeSearchGatewayEvent() {
        LogUtils.i("搜索网关--", "移除搜索网关监听");
        LogUtils.i("搜索网关", "移除搜索网关监听");
        EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_SEARCH_REPLY, searchGatewayEvent);
    }
@@ -544,4 +615,49 @@
        });
    }
    /**
     * 搜索在线所有的网关,包括当前住宅的及没有绑定过其它住宅的网关
     *
     * @param ipAddress 目标的IP地址
     * @param port      目标的端口
     * @param callBack  回调
     */
    public void searchGateway(String ipAddress, int port, SearchGatewayCallBack callBack) {
//        this.searchGatewayId = gatewayId;
//        this.mSearchGatewayCallBack = callBack;
//        //重置参数
//        searchGatewayCount.set(0);
//        isSearchGatewaySuccess.set(false);
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH,
                jsonObject.toString());
        //注册搜索网关监听
        registerSearchGatewayEvent();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (searchGatewayCount.get() < 10 && (!isSearchGatewaySuccess.get())) {
                    try {
                        //搜索网关
                        searchGatewayCount.set(searchGatewayCount.get() + 1);
                        LogUtils.i("搜索网关", "搜索网关第" + searchGatewayCount.get() + "次");
                        getUdpBoot().sendMsg(ipAddress, port, message.getSendBytes());
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (!isSearchGatewaySuccess.get()) {
                    //搜索10次,指定网关都没回复,回调超时
                    callBackSearchGatewayTimeout();
                    LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时");
                }
            }
        }).start();
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -50,40 +50,14 @@
 */
public class HDLSocket {
//    public interface CallBack extends BaseCallBack {
//        void onResponse(String data);
//    }
//
//    /**
//     * udp默认组播ip
//     */
//    private static final String UDP_GROUP_IP = "239.0.168.188";
    /**
     * udp默认端口
     */
    private static final int UDP_PORT = 8585;
    /**
     * tcp默认端口
     */
    private static final int TCP_PORT = 8586;
    //    private String tcpIp;
//    private int tcpPort;
//    private int udpPort;
//    private String udpIp;
//    private static SocketBoot updBoot;
    private SocketBoot tcpBoot;
    private ConnectStatusListener statusListener;
//    private EventListener searchEvent;
//    private CallBack searchCallBack;
//    private ScheduledExecutorService searchGatewayThread;
//    private final AtomicInteger searchCount = new AtomicInteger(0);
    private HDLSocket() {
        statusListener = new ConnectStatusListener() {
@@ -102,43 +76,6 @@
            }
        };
//        searchEvent = new EventListener() {
//            @Override
//            public void onMessage(Object msg) {
//                try {
//                    if (msg instanceof LinkResponse) {
//                        LinkResponse linkResponse = (LinkResponse) msg;
//                        String data = linkResponse.getData();
//                        if (!TextUtils.isEmpty(data)) {
//                            final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() {
//                            }.getType());
//                            GatewaySearchBean searchBean = response.getObjects();
//                            if (searchBean != null) {
////                                gatewayId = searchBean.getGatewayId();
////                                if (!TextUtils.isEmpty(gatewayId)) {
////                                    SPUtils.put(GATEWAY_KEY, gatewayId);
////                                }
////                                tcpIp = searchBean.getIp_address();
////                                if (!TextUtils.isEmpty(tcpIp)) {
////                                    SPUtils.put(TCP_IP_KEY, tcpIp);
////                                }
//                            }
//
//                            if (searchCallBack != null) {
//                                searchCallBack.onResponse(linkResponse.toString());
//                            }
//                        }
//
//                    }
//                } catch (Exception e) {
//                    if (searchCallBack != null) {
//                        searchCallBack.onError("解析失败");
//                    }
//                }
//
//
//            }
//        };
    }
    private static class SingletonInstance {
@@ -149,16 +86,6 @@
        return SingletonInstance.INSTANCE;
    }
//    private SocketOptions getUdpOptions() {
//        final SocketOptions options = new SocketOptions();
//        final MessagePipeLine pipeLine = new MessagePipeLine();
//        pipeLine.add(new LinkMessageDecoder());
//        pipeLine.add(new LinkMessageEncoder());
//        options.setHandleMessage(pipeLine);
//        options.setEnabledHeartbeat(false);
//        return options;
//    }
    private SocketOptions getTcpOptions() {
        final SocketOptions options = new SocketOptions();
@@ -173,9 +100,6 @@
        return options;
    }
    private int getUdpPort() {
        return UDP_PORT;
    }
    public int getTcpPort() {
        return TCP_PORT;
@@ -188,90 +112,6 @@
    public String getGatewayId() {
        return HDLLinkConfig.getInstance().getGatewayId();
    }
//    private String getUdpIp() {
//        if (TextUtils.isEmpty(udpIp)) {
//            udpIp = UDP_GROUP_IP;
//        }
//        return udpIp;
//    }
//    public void searchGateway() {
//        searchGateway(null);
//    }
//
//    /**
//     * 组播搜索
//     */
//    public void searchGateway(CallBack callBack) {
////        gatewayId = "";//重置网关ID
////        this.searchCallBack = callBack;
////
////        if (searchGatewayThread != null) {
////            searchGatewayThread.shutdownNow();
////        }
////
////
////        new Thread(new Runnable() {
////            @Override
////            public void run() {
////                while (TextUtils.isEmpty(gatewayId)) {
////                    //搜索网关
////                    searchGateway(IdUtils.getUUId(), searchEvent);
////                    try {
////                        Thread.sleep(1000L);
////                    } catch (InterruptedException e) {
////                        e.printStackTrace();
////                    }
////                }
////            }
////        }).start();
//    }
//
//
//    /**
//     * 通过组播搜索网关
//     */
//    public void searchGateway(String msgId, EventListener eventListener) {
//        searchGateway(getUdpIp(), getUdpPort(), msgId, eventListener);
//    }
//
//    /**
//     * 通过广播搜索网关
//     */
//    public void searchGatewayByBroadcast(String msgId, EventListener eventListener) {
//        searchGateway(IpUtils.getBroadcastAddress(), getUdpPort(), msgId, eventListener);
//    }
//
//    /**
//     * 默认是组播搜索网关
//     */
//    public void searchGateway(String ip, int port, String msgId, EventListener eventListener) {
//
//        if (updBoot == null) {
//            updBoot = UdpClient.init(ip, port, getUdpOptions());
//            updBoot.connect();
//        }
//
//
//        String time = String.valueOf(System.currentTimeMillis());
//        JsonObject jsonObject = new JsonObject();
//        jsonObject.addProperty("id", msgId);
//        jsonObject.addProperty("time_stamp", time);
//
//        EventDispatcher.getInstance().registerIo(TopicConstant.GATEWAY_SEARCH_REPLY, eventListener);
//        LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH,
//                jsonObject.toString());
//
//        try {
//            updBoot.sendMsg(message.getSendBytes());
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//
//    }
    /**
     * 获取设备列表
@@ -718,14 +558,14 @@
                @Override
                public void onMessage(Object msg) {
                    if (msg instanceof LinkResponse) {
                        LogUtils.e("sendMsg onSuccess");
                        LogUtils.i("sendMsg onSuccess");
                        threadPool.shutdownNow();
                        LogUtils.i("sendMsg eventListener remove");
                        EventDispatcher.getInstance().remove(eventTag, this);
                        if (callBack != null) {
                            callBack.onSuccess(msg.toString());
                        }
                        threadPool.shutdownNow();
                    }
                    LogUtils.e("sendMsg eventListener remove");
                    EventDispatcher.getInstance().remove(eventTag, this);
                }
            };
@@ -751,6 +591,7 @@
                }
            }, 1000, 500, TimeUnit.MILLISECONDS);
            EventDispatcher.getInstance().register(eventTag, eventListener);
            //先发送一次
            getTcp().sendMsg(data, new SendListener() {
                @Override
                public void onSucceed() {
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -4,10 +4,13 @@
import com.hdl.sdk.common.event.EventDispatcher;
import com.hdl.sdk.common.event.EventListener;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.connect.bean.LinkRequest;
import com.hdl.sdk.socket.SocketBoot;
import com.hdl.sdk.socket.udp.UdpSocketBoot;
import java.net.InetSocketAddress;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -25,17 +28,28 @@
    private final Long sendAwaitTime;
    private final int maxRetry;
    private final SocketBoot boot;
    private SocketBoot boot;
    private UdpSocketBoot udpSocketBoot;
    /**
     * 发送的目标IP
     */
    private String ipAddress;
    /**
     * 发送的目标地址
     */
    private int port;
    private final LinkRequest linkRequest;
    private final EventListener eventListener;
    private final AtomicInteger sendNumber;
    private final AtomicBoolean isSend = new AtomicBoolean();
    private final AtomicBoolean isSend = new AtomicBoolean(false);
    private final HdlSocketListener listener;
    private HdlSocketListener listener;
    private ScheduledExecutorService sendThread;
    private String observeTopic;
    public interface HdlSocketListener {
        void onSucceed(Object msg);
@@ -43,12 +57,16 @@
        void onFailure();
    }
    private HdlSocketHelper(Long sendAwaitTime, int maxRetry, SocketBoot boot, LinkRequest linkRequest, String observeTopic, HdlSocketListener listener) {
    private HdlSocketHelper(Long sendAwaitTime, int maxRetry, UdpSocketBoot udpSocketBoot,
                            String ipAddress, int port, LinkRequest linkRequest, String observeTopic, HdlSocketListener listener) {
        this.sendAwaitTime = sendAwaitTime;
        this.maxRetry = maxRetry;
        this.boot = boot;
        this.udpSocketBoot = udpSocketBoot;
        this.ipAddress = ipAddress;
        this.port = port;
        this.linkRequest = linkRequest;
        this.listener = listener;
        this.observeTopic = observeTopic;
        this.sendNumber = new AtomicInteger(0);
        eventListener = new EventListener() {
            @Override
@@ -60,61 +78,121 @@
                if (sendThread != null) {
                    sendThread.shutdownNow();
                }
                EventDispatcher.getInstance().remove(eventListener);
                //移除监听
                removeListener();
            }
        };
        EventDispatcher.getInstance().register(observeTopic, eventListener);
        //注册监听
        registerListener();
    }
    public static void send(SocketBoot boot, LinkRequest linkRequest, String observeTopic, HdlSocketListener listener, Long sendAwaitTime, int maxRetry) {
    /**
     * 注册监听
     */
    void registerListener() {
        if (!TextUtils.isEmpty(observeTopic)) {
            EventDispatcher.getInstance().register(observeTopic, eventListener);
//            LogUtils.i("HdlSocketHelper", "register event");
        }
    }
    /**
     * 移除监听
     */
    void removeListener() {
        if (!TextUtils.isEmpty(observeTopic)) {
            EventDispatcher.getInstance().remove(observeTopic, eventListener);
//            LogUtils.i("HdlSocketHelper", "remove event");
        }
    }
    /**
     * Udp的发送方法
     *
     * @param udpSocketBoot Udp当前对接
     * @param ipAddress     发送的目标IP地址
     * @param port          目的端口
     * @param linkRequest   发送的数据
     * @param observeTopic  发送的主题
     * @param retry         重发数次
     * @param listener      回调
     */
    public static void sendUdp(UdpSocketBoot udpSocketBoot, String ipAddress, int port, LinkRequest linkRequest, String observeTopic, int retry, HdlSocketListener listener) {
        if (TextUtils.isEmpty(observeTopic)) {
            observeTopic = linkRequest.getTopic() + "_reply";
        }
        HdlSocketHelper socketHelper = new HdlSocketHelper(sendAwaitTime, maxRetry, boot, linkRequest, observeTopic, listener);
        socketHelper.resend();
        HdlSocketHelper socketHelper = new HdlSocketHelper(DEF_SEND_TIMEOUT, retry, udpSocketBoot, ipAddress, port, linkRequest, observeTopic, listener);
        socketHelper.send();
    }
    public static void send(SocketBoot boot, LinkRequest linkRequest, String observeTopic, HdlSocketListener listener) {
        send(boot, linkRequest, observeTopic, listener, DEF_SEND_TIMEOUT, DEF_MAX_RETRY);
    /**
     * Udp的发送方法
     *
     * @param udpSocketBoot Udp当前对接
     * @param ipAddress     发送的目标IP地址
     * @param port          目的端口
     * @param linkRequest   发送的数据
     * @param listener      回调
     */
    public static void sendUdp(UdpSocketBoot udpSocketBoot, String ipAddress, int port, LinkRequest linkRequest, HdlSocketListener listener) {
        sendUdp(udpSocketBoot, ipAddress, port, linkRequest, "", DEF_MAX_RETRY, listener);
    }
    public static void send(SocketBoot boot, LinkRequest linkRequest, HdlSocketListener listener) {
        send(boot, linkRequest, "", listener, DEF_SEND_TIMEOUT, DEF_MAX_RETRY);
    /**
     * Udp的发送方法
     *
     * @param udpSocketBoot Udp当前对接
     * @param ipAddress     发送的目标IP地址
     * @param port          目的端口
     * @param linkRequest   发送的数据
     */
    public static void sendUdpOne(UdpSocketBoot udpSocketBoot, String ipAddress, int port, LinkRequest linkRequest) {
        HdlSocketHelper socketHelper = new HdlSocketHelper(DEF_SEND_TIMEOUT, DEF_SEND_ONE, udpSocketBoot, ipAddress, port, linkRequest, null, null);
        socketHelper.send();
    }
    public static void sendOne(SocketBoot boot, LinkRequest linkRequest, HdlSocketListener listener) {
        send(boot, linkRequest, "", listener, DEF_SEND_TIMEOUT, DEF_SEND_ONE);
    }
    private void resend() {
    private void send() {
        getSendThread().scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                if ((sendNumber.get() < maxRetry + 2) || !isSend.get()) {
                //发送次数小于重发次数
                if ((sendNumber.get() < maxRetry)) {
                    try {
                        if (sendNumber.get() < maxRetry + 1) {
                        //还没有收到回复,再发送
                        if (!isSend.get()) {
                            sendNumber.set(sendNumber.get() + 1);
                            //如是tcp
                            if (boot != null) {
                                boot.sendMsg(linkRequest.getSendBytes());
                            }
                            sendNumber.set(sendNumber.get() + 1);
                        } else {
                            notifyFailure();
                            //如果是udp
                            if (null != udpSocketBoot) {
                                udpSocketBoot.sendMsg(ipAddress, port, linkRequest.getSendBytes());
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        sendNumber.set(sendNumber.get() + 1);
                    } finally {
                        if (sendNumber.get() > maxRetry + 1 && !isSend.get()) {
                            notifyFailure();
                        }
                    }
                } else {
                    //超出重发次数并没有收到回复
                    if (!isSend.get()) {
                        notifyFailure();
                    }
                }
            }
        }, sendAwaitTime, sendAwaitTime, TimeUnit.MILLISECONDS);
        }, 0, sendAwaitTime, TimeUnit.MILLISECONDS);
        //initialdelay - 首次执行的延迟时间 0
        //delay - 一次执行终止和下一次执行开始之间的延迟
    }
    public ScheduledExecutorService getSendThread() {
    /**
     * 获取发送线程
     *
     * @return 返回获取到的线程
     */
    private ScheduledExecutorService getSendThread() {
        if (sendThread == null) {
            sendThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
        }
@@ -122,14 +200,19 @@
    }
    /**
     * 发送失败
     */
    private void notifyFailure() {
        //移除监听
        removeListener();
        if (sendThread != null) {
            sendThread.shutdownNow();
            sendThread = null;
        }
        if (listener != null) {
            listener.onFailure();
            listener = null;
        }
        EventDispatcher.getInstance().remove(eventListener);
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java
@@ -34,6 +34,10 @@
    private final IClient client;
    public IClient getClient() {
        return client;
    }
    /**
     * socket是否在运行
     */
@@ -127,12 +131,10 @@
            public void run() {
                while (isRun.get()) {
                    if (client.isConnect()) {
                        LogUtils.d("=====", "==发送数据==");
                        try {
                            SocketRequest socketRequest = mMessageQueue.take();
                            final String sendStr = new String(socketRequest.getData(), 0, socketRequest.getData().length);
                            LogUtils.d("=====", "==发送数据==:"+sendStr);
                            LogUtils.i("发送数据:"+sendStr);
                            final String action = socketRequest.getAction();
                            try {
                                client.sendMsg(socketRequest.getData());
@@ -172,28 +174,30 @@
    }
    /**
     * 初始化接收线程,只需要初始化一次
     */
    public void initReceiveThread() {
        if (receiveThread == null) {
            receiveThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
        }
        receiveThread.execute(new Runnable() {
            @Override
            public void run() {
                while (isRun.get()) {
                    if (client.isConnect()) {
                        try {
                            //读取数据
                            client.onHandleResponse();
                        } catch (Exception e) {
                            e.printStackTrace();
                            LogUtils.d("====", "断开连接" + e.getMessage());
                            disconnectError();
            receiveThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (isRun.get()) {
                        if (client.isConnect()) {
                            try {
                                //读取数据
                                client.onHandleResponse();
                            } catch (Exception e) {
                                e.printStackTrace();
                                disconnectError();
                            }
                        }
                    }
                    LogUtils.i("Socket 线程退出接收数据");
                }
            }
        });
            });
        }
    }
@@ -209,7 +213,7 @@
            @Override
            public void run() {
                if (isRun.get()) {
                    LogUtils.d("====", "===发送心跳包===");
//                    LogUtils.d("====", "===发送心跳包===");
                    if (client.getOptions() != null) {
                        final byte[] heartBeat = client.getOptions().getHeartbeatData();
                        if (heartBeat != null) {
@@ -258,7 +262,6 @@
        if (!client.isConnect()) {
            resetConnect(false);
        }
    }
    /**
@@ -278,7 +281,6 @@
                    if (!client.isConnect() && isOpenRetry.get()) {
                        resetConnect(false);
                    }
                }
            }, 3000, TimeUnit.MILLISECONDS);
        }
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java
@@ -14,6 +14,9 @@
 */
public class SocketOptions {
    //发送目标地址IP
    private String ip;
    //设置读取缓存
    private int readMaxBufferSize = 512;
@@ -45,6 +48,13 @@
    private int soTimeout;
    private boolean soLinger;
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public IHandleMessage getHandleMessage() {
        return handleMessage;
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketPool.java
@@ -51,5 +51,4 @@
        mUdpClientPool.put(address.toString(), socket);
        return socket;
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IUdpClient.java
New file
@@ -0,0 +1,42 @@
package com.hdl.sdk.socket.client;
import com.hdl.sdk.socket.SocketOptions;
import com.hdl.sdk.socket.udp.UdpSocketOptions;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
/**
 * Created by hxb on 2021/12/12.
 */
public interface IUdpClient {
    /**
     * 绑定端口
     */
    void bind() throws Exception;
    /**
     * 关闭当前连接
     * @return
     */
    boolean close();
    UdpSocketOptions getOptions();
    /**
     * 监听数据
     */
    void onHandleResponse() throws Exception;
    /**
     * 发送数据
     * @param ipAddress 目标IP
     * @param port 端口
     * @param msg 发送数据
     * @throws Exception
     */
    void sendMsg(String ipAddress,int port, byte[] msg) throws Exception;
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java
@@ -1,18 +1,16 @@
package com.hdl.sdk.socket.client;
import android.util.Log;
import android.text.TextUtils;
import com.hdl.sdk.common.HDLSdk;
import com.hdl.sdk.common.utils.IpUtils;
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;
import com.hdl.sdk.socket.SocketPool;
import com.hdl.sdk.socket.annotation.ConnectStatus;
import com.hdl.sdk.socket.udp.UdpSocketBoot;
import com.hdl.sdk.socket.udp.UdpSocketOptions;
import com.hdl.sdk.socket.codec.IHandleMessage;
import com.hdl.sdk.socket.listener.ConnectStatusListener;
import java.io.IOException;
import java.net.DatagramPacket;
@@ -20,190 +18,157 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
 * Created by Tong on 2021/9/15.
 * 组播需要android.permission.CHANGE_WIFI_MULTICAST_STATE权限
 * MulticastSocket
 * Created by hxb on 2021/12/12.
 */
public class UdpClient implements IClient {
    private static DatagramSocket mSocket;
    private DatagramPacket receivePacket;
    private final int BUFFER = 4 * 1024;
    private final byte[] receiveByte;
    private final String ip;
    private final int port;
    private int monitorPort;
    private int sendPort;
    private SocketOptions socketOptions;
    private final AtomicBoolean isConnect = new AtomicBoolean(false);
public class UdpClient implements IUdpClient {
    /**
     * @param sendPort -1 表示随机端口
     * 当前socket
     */
    private UdpClient(String ip, int port, int monitorPort, int sendPort, SocketOptions socketOptions) {
    private  DatagramSocket mSocket;
    /**
     * 接收数据包
     */
    private DatagramPacket receivePacket;
    /**
     * 缓冲区大小
     */
    private final int BUFFER = 2 * 1024;
    /**
     * 本地监听IP地址
     */
    private String ipAddress;
    /**
     * 本地监听端口
     */
    private int port;
    /**
     * socket配置信息
     */
    private UdpSocketOptions socketOptions;
    /**
     * 初始化参数
     * @param ipAddress 本地监听端口
     * @param port 本地监听端口
     * @param socketOptions
     */
    private UdpClient(String ipAddress,int port, UdpSocketOptions socketOptions) {
        this.ipAddress = ipAddress;
        this.port = port;
        this.socketOptions = socketOptions;
        this.ip = ip;
        this.port = port;
        this.sendPort = sendPort;
        this.monitorPort = monitorPort;
        this.receiveByte = new byte[BUFFER];
        byte[] receiveByte = new byte[BUFFER];
        receivePacket = new DatagramPacket(receiveByte, receiveByte.length);
    }
    public UdpClient(String ip, int port) {
        this.ip = ip;
        this.port = port;
        this.receiveByte = new byte[BUFFER];
    /**
     * 初始化参数
     * @param ipAddress 本地监听IP地址
     * @param port 本地监听端口
     * @param options
     * @return
     */
    public static UdpSocketBoot init(String ipAddress, int port, UdpSocketOptions options) {
        return new UdpSocketBoot(new UdpClient(ipAddress, port, options));
    }
    public static SocketBoot init(String ip, int port, int monitorPort, int sendPort, SocketOptions options) {
        return new SocketBoot(new UdpClient(ip, port, monitorPort, sendPort, options));
    /**
     * 初始化参数
     * @param port 本地监听端口
     * @param options
     * @return
     */
    public static UdpSocketBoot init(int port, UdpSocketOptions options) {
        return init(null, port, options);
    }
    public static SocketBoot init(String ip, int port, int monitorPort, SocketOptions options) {
        return init(ip, port, monitorPort, -1, options);
    }
    public static SocketBoot init(String ip, int port, SocketOptions options) {
        return init(ip, port, port, -1, options);
    }
    @Override
    public void connect() throws Exception {
    public void bind() throws Exception {
        try {
            mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(monitorPort));
            //已经绑定过就不用再绑定
            if (null != mSocket) {
                return;
            }
            if (TextUtils.isEmpty(ipAddress)) {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(port));
            }
            mSocket.setBroadcast(true);
            mSocket.setReuseAddress(true);
            isConnect.set(true);
            if (receivePacket == null) {
                receivePacket = new DatagramPacket(receiveByte, BUFFER);
            }
        } catch (Exception e) {
            isConnect.set(false);
            LogUtils.e("初始化Socket 失败:" + e.getMessage());
            throw e;
        }
    }
    @Override
    public void disconnect() {
        if (mSocket != null) {
    public boolean close() {
        try {
            mSocket.close();
        } catch (Exception e) {
        }
        isConnect.set(false);
        mSocket = null;
        return true;
    }
    @Override
    public boolean isConnect() {
        return isConnect.get();
    }
    @Override
    public synchronized SocketOptions getOptions() {
        if (socketOptions == null) {
            socketOptions = new SocketOptions();
        }
        return socketOptions;
    public UdpSocketOptions getOptions() {
        return this.socketOptions;
    }
    @Override
    public void onHandleResponse() throws Exception {
        if (receivePacket == null || mSocket == null) {
        if (mSocket == null) {
            return;
        }
        try {
           mSocket.receive(receivePacket);
            mSocket.receive(receivePacket);
        } catch (IOException e) {
            e.printStackTrace();
            isConnect.set(false);
        }
        if (receivePacket.getLength() == 0) {
            return;
        }
        //排除自己发出去的
        try {
            if (IpUtils.isLocalIpAddress( receivePacket.getAddress().getHostAddress()))
            if (IpUtils.isLocalIpAddress(receivePacket.getAddress().getHostAddress()))
                return;
        } catch (Exception ignored) {
        }
        IHandleMessage handleMessage = getOptions().getHandleMessage();
        if (handleMessage != null) {
            byte[] data = new byte[receivePacket.getLength()];
            System.arraycopy(receivePacket.getData(), 0, data, 0, data.length);
            handleMessage.read(data);
        }
        final String receive = new String(receivePacket.getData(), 0, receivePacket.getLength());
        try {
            LogUtils.i("接收到Udp数据包,网络地址:" + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
        LogUtils.d("---->", receive + " from " + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
        //重置长度
        if (receivePacket != null) {
            receivePacket.setLength(BUFFER);
        }
    }
    @Override
    public void sendMsg(byte[] msg) throws Exception {
        if (msg == null) {
            msg = new byte[1];
        }
        InetAddress serverAddress = InetAddress.getByName(ip);
        final DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, serverAddress, port);
        if (sendPort < 0) {
            final DatagramSocket sendSocket = new DatagramSocket();
            sendSocket.send(sendPacket);
            sendSocket.close();
        } else if (sendPort == monitorPort) {
            mSocket.send(sendPacket);
        } else {
            final DatagramSocket sendSocket = new DatagramSocket(sendPort);
            sendSocket.send(sendPacket);
            sendSocket.close();
        }
    }
    @Override
    public void onConnectStatus(int status) {
        ThreadToolUtils.getInstance().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final List<ConnectStatusListener> list = getOptions().getConnectStatusListener();
                if (list != null && !list.isEmpty()) {
                    for (ConnectStatusListener listener : list) {
                        switch (status) {
                            case ConnectStatus
                                    .CONNECTING:
                                listener.onConnecting();
                                break;
                            case ConnectStatus
                                    .CONNECTED:
                                listener.onConnected();
                                break;
                            case ConnectStatus
                                    .DISCONNECT:
                                listener.onConnectFailed();
                                break;
                        }
                    }
                }
            IHandleMessage handleMessage = getOptions().getHandleMessage();
            if (handleMessage != null) {
                byte[] data = new byte[receivePacket.getLength()];
                System.arraycopy(receivePacket.getData(), 0, data, 0, data.length);
                handleMessage.read(data);
            }
        });
        } catch (Exception e) {
        }
    }
    @Override
    public void sendMsg(String ipAddress,int port, byte[] msg) throws Exception {
        if (msg == null) {
            return;
        }
        final DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(ipAddress), port);
        mSocket.send(sendPacket);
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/udp/UdpSocketBoot.java
New file
@@ -0,0 +1,133 @@
package com.hdl.sdk.socket.udp;
import android.text.TextUtils;
import androidx.collection.ArrayMap;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.socket.SocketRequest;
import com.hdl.sdk.socket.annotation.ConnectStatus;
import com.hdl.sdk.socket.client.IClient;
import com.hdl.sdk.socket.client.IUdpClient;
import com.hdl.sdk.socket.listener.SendListener;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * Created by hxb on 2021/12/12.
 */
public class UdpSocketBoot {
    private final IUdpClient client;
    private final AtomicBoolean isOpenRetry = new AtomicBoolean(false);
    private final AtomicInteger resendCount = new AtomicInteger(0);
    private ExecutorService receiveThread;
    private final ArrayMap<String, SendListener> sendMap = new ArrayMap<>();
    public UdpSocketBoot(IUdpClient client) {
        this.client = client;
    }
    /**
     * 绑定 socket
     * @throws Exception 可能端口冲突
     */
    public void bind() throws Exception {
        client.bind();
        initReceiveThread();
    }
    /**
     * 初始化接收线程
     */
    private void initReceiveThread() {
        if(null!=receiveThread){
            return;
        }
        receiveThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
        receiveThread.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        client.onHandleResponse();
                    } catch (Exception e) {
                       LogUtils.i("接收线程异常:"+e.getMessage());
                    }
                }
            }
        });
    }
    /**
     * 发送数据
     * @param ipAddress 目的的IP地址
     * @param port 端口
     * @param msg 发送数据
     * @param listener 发送回调
     */
    public void sendMsg(String ipAddress,int port,byte[] msg, SendListener listener) {
        sendMsg(ipAddress,port, msg, true, listener);
    }
    /**
     * 发送数据
     * @param ipAddress 目的的IP地址
     * @param port 端口
     * @param msg 发送数据
     */
    public void sendMsg(String ipAddress,int port,byte[] msg) {
        sendMsg(ipAddress,port, msg, true, null);
    }
    /**
     * 发送数据
     * @param ipAddress 目的IP地址
     * @param port 端口
     * @param msg 发送的数据
     * @param isRefreshRetry 是否要重发
     * @param listener 发送回调
     */
    public void sendMsg(String ipAddress,int port, byte[] msg, boolean isRefreshRetry, SendListener listener) {
        if (isRefreshRetry) {
            //重置连接次数
            resendCount.set(0);
        }
        try {
            SocketRequest request = new SocketRequest(msg);
            if (listener != null && !TextUtils.isEmpty(request.getAction())) {
                sendMap.put(request.getAction(), listener);
            }
            client.sendMsg(ipAddress,port, msg);
        } catch (Exception e) {
            LogUtils.i("发送失败:" + e.getMessage());
        }
    }
    /**
     * 关闭当前socket
     */
    public synchronized void close() {
        isOpenRetry.set(false);
        sendMap.clear();
        receiveThread.shutdown();
        receiveThread=null;
        client.close();
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/udp/UdpSocketOptions.java
New file
@@ -0,0 +1,26 @@
package com.hdl.sdk.socket.udp;
import com.hdl.sdk.socket.codec.IHandleMessage;
import com.hdl.sdk.socket.listener.ConnectStatusListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by hxb on 2021/12/12.
 */
public class UdpSocketOptions {
    //处理数据
    private IHandleMessage handleMessage;
    public IHandleMessage getHandleMessage() {
        return handleMessage;
    }
    public void setHandleMessage(IHandleMessage handleMessage) {
        this.handleMessage = handleMessage;
    }
}
HDLSDK_DEMO/app/libs/hdl-common-V1.0.1.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.1.aar
Binary files differ
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.1.aar
Binary files differ
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -19,14 +19,17 @@
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.hdl.hdlsdk.device.DevicesListActivity;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.event.EventListener;
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.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.LinkRequest;
import com.hdl.sdk.connect.bean.LinkResponse;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.request.PropertyReadRequest;
@@ -100,13 +103,17 @@
        beans.add(new DemoBean("获取场景列表"));
        beans.add(new DemoBean("场景控制"));
        beans.add(new DemoBean("设备功能列表"));
        beans.add(new DemoBean("UDP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("TCP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("UDP发送,不回调不重发"));
        beans.add(new DemoBean("TCP发送,不回调不重发"));
        demoAdapter = new DemoAdapter(beans);
        rv.setAdapter(demoAdapter);
//        final SocketOptions options = new SocketOptions();
//
        MessagePipeLine pipeLine = new MessagePipeLine();
//        MessagePipeLine pipeLine = new MessagePipeLine();
//        options.setHandleMessage(pipeLine);
//        options.setEnabledHeartbeat(false);
@@ -150,10 +157,29 @@
                        //功能列表
                        startDevicesListActivity();
                        break;
                    case 9:
                        //UDP发送
                        udpSendWithCallback();
                        break;
                    case 10:
                        //TCP发送
                        tcpSendWithCallback();
                    case 11:
                        //UDP发送
                        udpSend();
                        break;
                    case 12:
                        //TCP发送
                        tcpSend();
                        break;
                }
            }
        });
    }
    public void showToast(String text) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }
@@ -176,13 +202,6 @@
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse)msg;
                if(response != null){
                    Log.i(TAG, "AllTopicsListener"
                            + "\nTopic: " + response.getTopic()
                            +"\n Data: " + response.getData());
                    handleLinkResponse(response);
                }
            }
        };
        HDLLink.getInstance().registerAllTopicsListener(allTopicsListener);
@@ -238,9 +257,9 @@
        tv.setText("开始入网认证...");
        //认证提交参数准备
        String spkStr = "ir.module";//产品spk
        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
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
@@ -248,7 +267,7 @@
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("HDL");
        requestBean.setSupplier("raysgem");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
@@ -263,7 +282,7 @@
        infoBean.setDeviceName("红外宝");//设备名字
        infoBean.setDeviceModel("HDL");//
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.12.1");
        infoBean.setIPGateway("192.168.88.1");
        infoBean.setIPAddress(IpUtils.getIP(this));
        infoBean.setOID("010105000000FE08");
@@ -476,4 +495,70 @@
        Intent intent = new Intent(this, DevicesListActivity.class);
        startActivity(intent);
    }
    /**
     * TCP发送,监听主题回复,带重发带回调
     */
    private void tcpSendWithCallback() {
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().tcpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString(), new HDLLinkCallBack() {
            @Override
            public void onSuccess(String data) {
                responseTv.setText(data);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * UDP发送,监听主题回复,带重发带回调
     */
    private void udpSendWithCallback() {
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().udpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString(), new HDLLinkResponseCallBack() {
            @Override
            public void onSuccess(LinkResponse linkResponse) {
                if(linkResponse != null){
                    responseTv.setText(linkResponse.getData());
                }
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * TCP发送 只发一次,不监听回复,不重发
     */
    private void tcpSend() {
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().tcpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString());
    }
    /**
     * 只发一次,不监听回复,不重发
     */
    private void udpSend() {
        String time = String.valueOf(System.currentTimeMillis());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", IdUtils.getUUId());
        jsonObject.addProperty("time_stamp", time);
        HDLLink.getInstance().udpSendMsg(TopicConstant.GATEWAY_SEARCH, jsonObject.toString());
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java
@@ -1,16 +1,34 @@
package com.hdl.hdlsdk.device;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.hdl.hdlsdk.DemoBean;
import com.hdl.hdlsdk.R;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.IdUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import java.util.ArrayList;
import java.util.List;
public class DevicesListAdapter extends RecyclerView.Adapter<DevicesListAdapter.ViewHolder> {
@@ -46,6 +64,12 @@
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.item_tv.setText(mList.get(position).getName());
        holder.device_on_off_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                propertyDown(mList.get(position), isChecked);
            }
        });
    }
    @Override
@@ -56,10 +80,39 @@
    //自定义的ViewHolder,持有每个Item的的所有界面元素
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView item_tv;
        public Switch device_on_off_switch;
        public ViewHolder(View view) {
            super(view);
            item_tv = (TextView) view.findViewById(R.id.device_title_tv);
            device_on_off_switch = view.findViewById(R.id.device_on_off_switch);
        }
    }
    private void propertyDown(FunctionBean functionBean, Boolean isOn){
        List<DeviceControlRequest> requestList = new ArrayList<>();
        DeviceControlRequest request = new DeviceControlRequest();
        request.setSid(functionBean.getSid());
        List<DeviceControlRequest.StatusBean>  statusBeanList= new ArrayList<>();
        DeviceControlRequest.StatusBean bean =  new DeviceControlRequest.StatusBean();
        bean.setKey("on_off");
        bean.setValue(isOn ? "on" : "off");
        statusBeanList.add(bean);
        request.setStatus(statusBeanList);
        requestList.add(request);
        String time = String.valueOf(System.currentTimeMillis());
        HDLLink.getInstance().propertyDown(requestList, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String data) {
                Log.i("propertyDown",data);
            }
            @Override
            public void onError(HDLLinkException e) {
                Log.e("propertyDown", "ERROR :"+ e.getMsg());
            }
        });
    }
}