562935844@qq.com
2023-10-18 755e2893c12b79649ee12dec2b7d832d58b9265b
上报oid列表新增parentoid
8个文件已添加
1个文件已删除
20个文件已修改
1601 ■■■■ 已修改文件
HDLSDK/.idea/gradle.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/com.hdl.sdk/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/com.hdl.sdk/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/config/TopicConstant.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/utils/AllTopicManagerUtils.java 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AttributesRequest.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BaseRequest.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/GatewayInfoRequest.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/GatewayRemoteEditRequest.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/ListSidRequest.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/ListUploadRequest.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/AuthenticateResponse.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/DeviceDeleteResponse.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/DeviceInfoResponse.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/NetworkAccessBroadcastResponse.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java 333 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/socket/client/UdpClient.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/build.gradle 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.1.4.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.1.6.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 259 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/.idea/gradle.xml
@@ -7,7 +7,7 @@
        <option name="testRunner" value="GRADLE" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="gradleJvm" value="JDK" />
        <option name="gradleJvm" value="Embedded JDK" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -5,7 +5,6 @@
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -18,7 +17,6 @@
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -31,15 +29,19 @@
import com.hdl.sdk.common.event.DeleteNetworkListener;
import com.hdl.sdk.common.event.EventListener;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.AllTopicManagerUtils;
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.LinkResponse;
import com.hdl.sdk.connect.bean.request.AttributesRequest;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.ListSidRequest;
import com.hdl.sdk.connect.bean.request.ListUploadRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.bean.response.DeviceInfoResponse;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
@@ -66,30 +68,6 @@
    private EventListener allTopicsListener;
    private String testLightSid = "02010131D9C03D01020300010107";
    private String secret = "";
    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeAllTopicsListener();
    }
    void initDeviceInfo() {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("音乐播放器");//设备名字
        infoBean.setDeviceModel("MCLog.431");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.1.1");
        infoBean.setIPAddress("192.168.1.103");
        infoBean.setGateway_type("screen.touch");//spk
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /*void applyDeviceSecret() {
        tv.setText("开始申请设备密钥...");
@@ -159,65 +137,6 @@
    }*/
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
        responseTv.setText("");
        //认证提交参数准备
//
//        //测试服务器
//        String spkStr = "music.standard";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.touch";//产品spk
//        String macStr = "AA00000000000100";//设备唯一MAC地址
        String macStr = editText.getText().toString();//设备唯一MAC地址
//        String secret = "e186beeb7974998e";//通过spk和mac提交云端认证后分配的secret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
//        HDLLinkConfig.getInstance().setCurrentGateway(infoBean);
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
//        HDLLinkConfig.getInstance().setRequestBean(requestBean);
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        HDLLinkConfig.getInstance().setAuthBean(authbean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败" + e.getCode());
                responseTv.setText(e.getMsg());
                Log.e(TAG, "onError: 认证失败 " + e.getCode());
            }
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
                localSecret.setText("密钥:" + HDLLinkConfig.getInstance().getLocalSecret());
            }
        });
    }
    public void UploadDeviceAuth(String mac, String result, String message, String auth_code) {
        //将认证结果上报给网关
        HDLLink.getInstance().UploadDeviceAuth(mac, result, message, auth_code, new HDLLinkCallBack() {
@@ -263,6 +182,8 @@
                LogUtils.i("setDeleteNetworkListener onFailure");
            }
        });
        UploadSidList();
        ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
@@ -456,6 +377,75 @@
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    void initDeviceInfo()
    {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("魔镜");//设备名字
        infoBean.setDeviceModel("HDLSDK");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.1.1");
        infoBean.setIPAddress("192.168.1.116");
        infoBean.setGateway_type("screen.touch");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
        //认证提交参数准备
//        测试服务
//        String spkStr = "ir.module";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.mirror";//产品spk
        String macStr = "f2c5d8bad48f";//设备唯一MAC地址
//        String secret = "e186beeb7974998e";//通过spk和mac提交云端认证后分配的secret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败");
                responseTv.setText(e.getMsg());
                Log.i("TAG", "onError: 认证失败");
            }
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
            }
        });
    }
    String stringToMD5(String text) {
        byte[] hash;
@@ -818,6 +808,47 @@
        });
    }
    private void UploadSidList() {
        tv.setText("上报Sid列表...");
        responseTv.setText("");
        //1.设置设备信息
        AuthenticateRequest.AuthenticateDeviceInfoBean authenticateDeviceInfoBean = HDLLinkConfig.getInstance().getDeviceInfoBean();
        ListSidRequest request = new ListSidRequest();
        request.setOid(authenticateDeviceInfoBean.getOID());
        request.setName("sid名称");
        request.setOmodel(authenticateDeviceInfoBean.getDeviceModel());
        request.setSid("12345678");//当前sid的
        request.setSpk("light.switch");//当前spk名称,根据实际设备来定义
        request.setFrom(authenticateDeviceInfoBean.getOID());//来自哪个网关,如果时Link网络设备,则填自身oid;如果是驱动则不需要此字段
        AttributesRequest attributes = new AttributesRequest();
        attributes.setKey("on_off");
        attributes.setData_type("string");
        List<Object> valueList=new ArrayList<>();
        valueList.add("on");
        valueList.add("off");
        attributes.setValue(valueList);
        //添加支持的属性列表
        List<AttributesRequest> attributesList = new ArrayList<>();
        request.setAttributes(attributesList);
        List<ListSidRequest> sidRequestList = new ArrayList<>();
        sidRequestList.add(request);
        HDLLink.getInstance().UploadSidList(sidRequestList, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException error) {
                tv.setText(error.getMsg());
            }
            @Override
            public void onSuccess(String data) {
                tv.setText("上报sid列表成功");
                responseTv.setText(data);
            }
        });
    }
    /**
     * 获取APP版本
     *
@@ -839,4 +870,10 @@
        return versionName;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeAllTopicsListener();
    }
}
HDLSDK/com.hdl.sdk/.DS_Store
Binary files differ
HDLSDK/com.hdl.sdk/build.gradle
@@ -8,8 +8,8 @@
    defaultConfig {
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 6
        versionName "1.1.4"
        versionCode 117
        versionName "1.1.7"
    }
    buildTypes {
        debug {
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java
@@ -1,10 +1,13 @@
package com.hdl.sdk.common;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
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.AllTopicManagerUtils;
import com.hdl.sdk.common.utils.IdUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.gson.GsonConvert;
@@ -32,7 +35,7 @@
        return version;
    }
    private String version = "1.1.0";
    private String version = "1.1.7";
    private HDLSdk() {
    }
@@ -46,10 +49,24 @@
    }
    public void init(Context context) {
        if (this.context != null) {
            return;
        }
        this.context = context.getApplicationContext();
        HDLAuthSocket.getInstance().init();
        HDLSocket.getInstance().broadcastRequest();
        LogUtils.i("HDLSdk Version:" + version);
        //订阅所有的主题
        HDLLink.getInstance().registerAllTopicsListener(new EventListener() {
            @Override
            public void onMessage(Object msg) {
                if (msg == null || !(msg instanceof LinkResponse)) {
                    return;
                }
                AllTopicManagerUtils.manager((LinkResponse) msg);
            }
        });
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/config/TopicConstant.java
@@ -121,5 +121,22 @@
    //驱动上报oid列表回复
    public static final String LIST_UPLOAD_REPLY = "/user/%s/custom/device/list/upload_reply";
    /**
     * sid列表上报
     */
    public static final String LIST_SID_UPLOAD="/base/%s/thing/topo/list/upload";
    /**
     * sid列表上报回复
     */
    public static final String LIST_SID_UPLOAD_REPLY="/base/%s/thing/topo/list/upload_reply";
    /*
     * 网关编辑命令
     * 写远程信息的,例如服务器地址、HomeId、密钥之类
     * 与服务器相关的
     * */
    public static final String GATEWAY_EDIT_REMOTE = "/user/%s/custom/gateway/remote/edit";
    public static final String GATEWAY_EDIT_REMOTE_REPLY = "/user/%s/custom/gateway/remote/edit_reply";
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/utils/AllTopicManagerUtils.java
New file
@@ -0,0 +1,196 @@
package com.hdl.sdk.common.utils;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import com.google.gson.reflect.TypeToken;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.LinkResponse;
import com.hdl.sdk.connect.bean.request.GatewayRemoteEditRequest;
import com.hdl.sdk.connect.bean.response.DeviceDeleteResponse;
import com.hdl.sdk.connect.bean.response.DeviceInfoResponse;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
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.utils.AesUtil;
/**
 * Created by hxb on 2023/9/14.
 */
public class AllTopicManagerUtils {
    /**
     * 全局主题处理方法,可以处理所有接收到的数据
     *
     * @param linkResponse
     */
    public static void manager(LinkResponse linkResponse) {
        try {
            if (linkResponse == null) {
                return;
            }
            String topic = linkResponse.getTopic();
            if (TextUtils.isEmpty(topic)) {
                return;
            }
            String[] topics = topic.split("/");
            //非当前住宅网关的数据返回
            if (topics.length < 3) {
                return;
            }
            String mac_Oid_GatewayId = topics[2];
            if (!isLocalDevice(mac_Oid_GatewayId)) {
                LogUtils.i("不是当前设备的网关Id,Id是" + mac_Oid_GatewayId);
                //非当前设备的数据
                return;
            }
            if (isSameTopic(TopicConstant.GATEWAY_EDIT_REMOTE, topic)) {
                gatewayRemoteEditRequest(mac_Oid_GatewayId, linkResponse.getData());
            } else if (isSameTopic(TopicConstant.GATEWAY_SEARCH, topic)) {
                HDLAuthSocket.getInstance().UploadGatewayInfo(null);
            } else if (isSameTopic(TopicConstant.LINK_BROADCAST, topic)) {
                managerLinkBroadcast(linkResponse.getData());
            } else if (isSameTopic(TopicConstant.DELETE_NOTIFY, topic)) {
                managerDeleteNofity(linkResponse.getData());
            }
        } catch (Exception e) {
            LogUtils.e("全局处理模块异常:" + e.getMessage());
        }
    }
    /**
     * 是否当前的设备
     *
     * @param mac_Oid_GatewayId
     * @return
     */
    private static boolean isLocalDevice(String mac_Oid_GatewayId) {
        if (TextUtils.isEmpty(mac_Oid_GatewayId)) {
            return false;
        }
        String mac = HDLLinkConfig.getInstance().getDeviceInfoBean().getDeviceMAC();
        String oid = HDLLinkConfig.getInstance().getDeviceInfoBean().getOID();
        String gatewayId = HDLLinkConfig.getInstance().getGatewayId();
        String all = "all";
        return mac_Oid_GatewayId.equals(mac) || mac_Oid_GatewayId.equals(oid) || mac_Oid_GatewayId.equals(gatewayId) || mac_Oid_GatewayId.toLowerCase().equals(all);
    }
    /**
     * 是否相同主题
     *
     * @param targetTopic 目标的主题
     * @param sourceTopic 接收的主题
     * @return
     */
    private static boolean isSameTopic(String targetTopic, String sourceTopic) {
        if (TextUtils.isEmpty(targetTopic) || TextUtils.isEmpty(sourceTopic)) {
            return false;
        }
        String[] targetTopics = targetTopic.split("/");
        String[] sourceTopics = sourceTopic.split("/");
        if (targetTopics.length != sourceTopics.length) {
            return false;
        }
        for (int i = 0; i < targetTopics.length; i++) {
            if (i == 2) {
                //这个位置不匹配,是网关id
                continue;
            }
            if (!targetTopics[i].equals(sourceTopics[i])) {
                return false;
            }
        }
        return true;
    }
    /**
     * 网关信息配置
     *
     * @param body
     */
    private static void gatewayRemoteEditRequest(String mac_Oid_GatewayId, String body) {
        if (TextUtils.isEmpty(body)) {
            return;
        }
        GatewayRemoteEditRequest gatewayRemoteEditRequest = GsonConvert.getGson().fromJson(body, new TypeToken<GatewayRemoteEditRequest>() {
        }.getType());
        if (gatewayRemoteEditRequest == null || gatewayRemoteEditRequest.getObjects() == null) {
            return;
        }
        String homeId = gatewayRemoteEditRequest.getObjects().getHomeId();
        HDLLinkConfig.getInstance().setHomeId(homeId);
        HDLSocket.getInstance().gatewayRemoteEditReply(mac_Oid_GatewayId, gatewayRemoteEditRequest.getId(), null);
    }
    /**
     * 更新密钥
     *
     * @param body
     */
    private static void managerLinkBroadcast(String body) {
        try {
            DeviceInfoResponse deviceInfoResponse = GsonConvert.getGson().fromJson(body, new TypeToken<DeviceInfoResponse>() {
            }.getType());
            if (deviceInfoResponse == null || deviceInfoResponse.getObjects() == null) {
                return;
            }
            if (!TextUtils.isEmpty(deviceInfoResponse.getObjects().getLocalSecret())) {
                byte[] baseBytes = Base64.decode(deviceInfoResponse.getObjects().getLocalSecret(), Base64.NO_WRAP);
                String mackey = "";
                if (!TextUtils.isEmpty(SPUtils.getString("auth_mackey_key", ""))) {
                    mackey = SPUtils.getString("auth_mackey_key", "");
                    byte[] bodyBytes = AesUtil.aesDecrypt(baseBytes, mackey.substring(mackey.length() - 16));
                    String localSecret = new String(bodyBytes, "utf-8");
                    Log.d("panlili", "更新密钥----->localSecret= " + localSecret);
                    HDLLinkConfig.getInstance().setLocalSecret(localSecret);
                }
            }
        } catch (Exception e) {
            LogUtils.i("LinkMessageDecoder.java:getLocalSecret----->e= " + e.getMessage());
        }
    }
    /**
     * 退网
     *
     * @param body
     */
    private static void managerDeleteNofity(String body) {
        try {
            DeviceDeleteResponse deviceDeleteResponse = GsonConvert.getGson().fromJson(body, new TypeToken<DeviceDeleteResponse>() {
            }.getType());
            if (deviceDeleteResponse == null || deviceDeleteResponse.getObjects() == null) {
                return;
            }
            HDLSocket.getInstance().deleteNetwork(deviceDeleteResponse.getObjects().get(0).getOID(), new HDLLinkCallBack() {
                @Override
                public void onSuccess(String msg) {
                }
                @Override
                public void onError(HDLLinkException e) {
                }
            });
        } catch (Exception e) {
            LogUtils.i("LinkMessageDecoder.java:deleteNetwork----->e= " + e.getMessage());
        }
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java
@@ -6,6 +6,7 @@
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.ListSidRequest;
import com.hdl.sdk.connect.bean.request.ListUploadRequest;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
@@ -102,6 +103,10 @@
    public void selectNetwork(String networkName) {
        HDLLinkConfig.getInstance().setNetworkName(networkName);
    }
    public void setParentOid(String parentOid) {
        HDLLinkConfig.getInstance().setParentOid(parentOid);
    }
    /**
@@ -306,6 +311,16 @@
    }
    /**
     * 上报sid列表
     *
     * @param requestList  sid列表
     * @param callBack 回调
     */
    public void UploadSidList(List<ListSidRequest> requestList, HDLLinkCallBack callBack) {
        HDLSocket.getInstance().UploadSidList(requestList, callBack);
    }
    /**
     * 通用UDP发送指令
     * 1秒没响应就让他重新发送,重试3次
     *
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AttributesRequest.java
New file
@@ -0,0 +1,37 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
import java.util.List;
/**
 * Created by hxb on 2023/9/14.
 */
public class AttributesRequest implements Serializable {
    private String key;//key名称
    private String data_type;//数据类型
    private List<Object> value;//值
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getData_type() {
        return data_type;
    }
    public void setData_type(String data_type) {
        this.data_type = data_type;
    }
    public List<Object> getValue() {
        return value;
    }
    public void setValue(List<Object> value) {
        this.value = value;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BaseRequest.java
New file
@@ -0,0 +1,30 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
/**
 * Created by jlchen on 11/15/21.
 *
 * @Description : BaseResponse
 */
public class BaseRequest implements Serializable {
    private String id;
    private String time_stamp;
    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;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/GatewayInfoRequest.java
@@ -23,6 +23,8 @@
    private String master;
    private boolean isLocalEncrypt;
    private String homeId;
    public String getOid() {
        return oid;
    }
@@ -126,4 +128,12 @@
    public void setLocalEncrypt(boolean localEncrypt) {
        isLocalEncrypt = localEncrypt;
    }
    public String getHomeId() {
        return homeId;
    }
    public void setHomeId(String homeId) {
        this.homeId = homeId;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/GatewayRemoteEditRequest.java
New file
@@ -0,0 +1,49 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
/**
 * Created by hxb on 2023/9/14.
 */
public class GatewayRemoteEditRequest extends BaseRequest {
    private GatewayObjects objects;
    public GatewayObjects getObjects() {
        return objects;
    }
    public void setObjects(GatewayObjects value) {
        this.objects = value;
    }
    public static class GatewayObjects implements Serializable {
        /**
         * 住宅Id
         */
        private String homeId;
        /**
         * 服务器地址
         */
        private String server_addr;
        public String getHomeId() {
            return homeId;
        }
        public void setHomeId(String homeId) {
            this.homeId = homeId;
        }
        public String getServer_addr() {
            return server_addr;
        }
        public void setServer_addr(String server_addr) {
            this.server_addr = server_addr;
        }
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/ListSidRequest.java
New file
@@ -0,0 +1,107 @@
package com.hdl.sdk.connect.bean.request;
import java.util.List;
/**
 * Created by panlili on 2023/1/31
 * description:获取sid列表
 */
public class ListSidRequest {
    /**
     * 是否在线
     */
    private String online;
    /**
     * 父oid
     */
    private String from;
    /**
     * 支持的属性列表
     */
    private List<AttributesRequest> attributes;
    /**
     * sid
     */
    private String sid;
    /**
     * spk
     */
    private String spk;
    /**
     * 当前oid
     */
    private String oid;//设备的Oid
    /**
     * 回路备注
     */
    private String name;
    /**
     * 模块信息
     */
    private String omodel;
    public String getOid() {
        return oid;
    }
    public void setOid(String oid) {
        this.oid = oid;
    }
    public String getOnline() {
        return online;
    }
    public void setOnline(String online) {
        this.online = online;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
    public List<AttributesRequest> getAttributes() {
        return attributes;
    }
    public void setAttributes(List<AttributesRequest> attributes) {
        this.attributes = attributes;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getSpk() {
        return spk;
    }
    public void setSpk(String spk) {
        this.spk = spk;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getOmodel() {
        return omodel;
    }
    public void setOmodel(String omodel) {
        this.omodel = omodel;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/ListUploadRequest.java
@@ -18,6 +18,7 @@
    private String src;//来自哪个驱动,如Link设备没有则填"LINK"
    private String from;//来自哪个网关,如果时Link网络设备,则填自身oid;如果是驱动则不需要此字段
    private List<ImageInfo> image_info;
    private String parentOid;//从机需要上报Parentoid,内容为主机的oid
    public String getOid() {
        return oid;
@@ -83,6 +84,14 @@
        this.from = from;
    }
    public String getParentOid() {
        return parentOid;
    }
    public void setParentOid(String parentOid) {
        this.parentOid = parentOid;
    }
    public List<ImageInfo> getImage_info() {
        return image_info;
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/AuthenticateResponse.java
@@ -32,7 +32,7 @@
        this.ip_address = ip_address;
    }
    public class Auth implements Serializable {
    public static class Auth implements Serializable {
        private String localSecret;
        public String getLocalSecret() { return localSecret; }
@@ -42,10 +42,12 @@
    }
    public class GatewayObjects implements Serializable  {
    public static class GatewayObjects implements Serializable  {
        private String ip_address;
        private String gatewayId;
        private String oid;
        private String homeId;
        public String getIPAddress() { return ip_address; }
        public void setIPAddress(String value) {
@@ -59,6 +61,14 @@
        public String getOID() { return oid; }
        public void setOID(String value) { this.oid = value; }
        public String getHomeId() {
            return homeId;
        }
        public void setHomeId(String homeId) {
            this.homeId = homeId;
        }
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/DeviceDeleteResponse.java
@@ -19,7 +19,7 @@
        this.objects = objects;
    }
    public class GatewayObjects implements Serializable {
    public static class GatewayObjects implements Serializable {
        private String device_name;
        private String oid;
        private boolean isSaveOidInfo;
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/DeviceInfoResponse.java
@@ -18,7 +18,7 @@
        this.objects = value;
    }
    public class GatewayObjects implements Serializable {
    public static class GatewayObjects implements Serializable {
        private String ip_address;
        private String gatewayId;
        private String oid;
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/response/NetworkAccessBroadcastResponse.java
@@ -10,6 +10,11 @@
    private String oid;
    private String homeId;
    /**
     * 需要入网从机mac
     */
    private String slave_mac;
    public String getIPAddress() { return ip_address; }
    public void setIPAddress(String value) { this.ip_address = value; }
@@ -18,4 +23,12 @@
    public String getHomeID() { return homeId; }
    public void setHomeID(String value) { this.homeId = value; }
    public String getSlave_mac() {
        return slave_mac;
    }
    public void setSlave_mac(String slave_mac) {
        this.slave_mac = slave_mac;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java
@@ -21,11 +21,15 @@
    private static final String AUTHENTICATE_IS_LS_KEY = "auth_isls_key";
    public static final String AUTHENTICATE_IS_DEVICEINFO_KEY = "auth_deviceinfo_key";
    public static final String GATEWAY_REMOTEINFO_KEY="gateway_remoteinfo_key";
    private String localSecret;//本地加密密钥
    private String gatewayId;
    private String ipAddress;
    private GatewaySearchBean currentGateway;//当前网关
    private String networkName;
    private String homeId;
    private String parentOid;
    private AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean;//当前设备基本信息
    private AuthenticateRequest.RequestBean requestBean;//当前设备基本信息
@@ -64,10 +68,12 @@
        this.gatewayId = "";
        this.ipAddress = "";
        this.localSecret = "";
        this.homeId="";
        SPUtils.remove(AUTHENTICATE_LS_KEY);
        SPUtils.remove(AUTHENTICATE_GATEWAYID_KEY);
        SPUtils.remove(AUTHENTICATE_IPADDRESS_KEY);
        SPUtils.remove(AUTHENTICATE_IS_LS_KEY);
        SPUtils.remove(GATEWAY_REMOTEINFO_KEY);
    }
    /**
@@ -77,6 +83,7 @@
        localSecret = SPUtils.getString(AUTHENTICATE_LS_KEY, "");
        gatewayId = SPUtils.getString(AUTHENTICATE_GATEWAYID_KEY, "");
        ipAddress = SPUtils.getString(AUTHENTICATE_IPADDRESS_KEY, "");
        homeId = SPUtils.getString(GATEWAY_REMOTEINFO_KEY, "");
    }
    /**
@@ -93,6 +100,7 @@
        SPUtils.put(AUTHENTICATE_LS_KEY, localSecret);
        SPUtils.put(AUTHENTICATE_GATEWAYID_KEY, gatewayId);
        SPUtils.put(AUTHENTICATE_IPADDRESS_KEY, ipAddress);
    }
    /**
@@ -136,6 +144,14 @@
    }
    public void setIpAddress(String ipAddress){
        this.ipAddress = ipAddress;
    }
    public String getParentOid() {
        return parentOid;
    }
    public void setParentOid(String parentOid) {
        this.parentOid = parentOid;
    }
    public String getNetworkName() {
@@ -189,6 +205,9 @@
    public AuthenticateRequest.AuthenticateDeviceInfoBean getDeviceInfoBean() {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = (AuthenticateRequest.AuthenticateDeviceInfoBean) SPUtils.getSerializableEntity(AUTHENTICATE_IS_DEVICEINFO_KEY);
        if(infoBean==null){
            infoBean= new AuthenticateRequest.AuthenticateDeviceInfoBean();
        }
        return infoBean;
    }
@@ -212,4 +231,13 @@
    public void setAuthBean(AuthenticateRequest.AuthBean authBean) {
        this.authBean = authBean;
    }
    public String getHomeId() {
        return homeId;
    }
    public void setHomeId(String homeId) {
        this.homeId = homeId;
        SPUtils.put(GATEWAY_REMOTEINFO_KEY, homeId);
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
@@ -24,8 +24,11 @@
import com.hdl.sdk.connect.socket.HDLAuthSocket;
import com.hdl.sdk.connect.socket.HDLSocket;
import com.hdl.sdk.connect.utils.AesUtil;
import com.hdl.sdk.connect.utils.ByteBufferUtils;
import com.hdl.sdk.socket.codec.ByteToMessageDecoder;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -38,13 +41,31 @@
 */
public class LinkMessageDecoder extends ByteToMessageDecoder<LinkResponse> {
    private final List<Byte> bytes;
    private static final String TAG = LinkMessageDecoder.class.getName();
    //instance
    private volatile static LinkMessageDecoder instance;
    //getInstance
    public static synchronized LinkMessageDecoder getInstance() {
        if (instance == null) {
            synchronized (LinkMessageDecoder.class) {
                if (instance == null) {
                    instance = new LinkMessageDecoder();
                }
            }
        }
        return instance;
    }
    /**
     * 接收数据缓冲区
     */
    private final ByteBuffer byteBuffer;
    private final byte[] head = "Topic:".getBytes();
//    private final byte[] body = "\r\n\r\n".getBytes();
    public LinkMessageDecoder() {
        this.bytes = new ArrayList<>();
        byteBuffer = ByteBuffer.allocate(1024 * 200);//100K
    }
    /// <summary>
@@ -53,11 +74,16 @@
    /// <param name="topMsgs"></param>
    /// <returns></returns>
    int getLenght(String[] topMsgs) {
        for (int i = 0; i < topMsgs.length; i++) {
            String topMsg = topMsgs[i].trim();
            if (topMsg.startsWith("Length:")) {
                return Integer.parseInt(topMsg.replace("Length:", ""));
        try {
            for (int i = 0; i < topMsgs.length; i++) {
                String topMsg = topMsgs[i].trim();
                if (topMsg.startsWith("Length:")) {
                    return Integer.parseInt(topMsg.replace("Length:", "").trim());
                }
            }
        } catch (Exception e) {
            LogUtils.e("异常数据:" + topMsgs[0] + "\r\n" + topMsgs[1]);
            return -1;
        }
        //找不到长度
        return -1;
@@ -82,15 +108,14 @@
    /**
     * 获取数据的开始位置
     *
     * @param arrayList 接收到的所有数据
     * @return 数据位的开始索引
     */
    int getDataIndex(List<Byte> arrayList) {
    int getBodyIndex() {
        byte r = (byte) '\r';
        byte n = (byte) '\n';
        for (int i = 0; i < arrayList.size(); i++) {
        for (int i = 0; i < byteBuffer.position(); i++) {
            //找出数据内容前面的两个换行
            if (3 <= i && arrayList.get(i - 3) == r && arrayList.get(i - 2) == n && arrayList.get(i - 1) == r && arrayList.get(i) == n) {
            if (3 <= i && byteBuffer.get(i - 3) == r && byteBuffer.get(i - 2) == n && byteBuffer.get(i - 1) == r && byteBuffer.get(i) == n) {
                //剩余的数据
                return i + 1;
            }
@@ -98,14 +123,73 @@
        return -1;
    }
    void initReceiveData(List<Byte> list) {
    /**
     * 获取头部数据
     *
     * @return
     */
    String getHeader() {
        int bodyIndex = getBodyIndex();
        if (bodyIndex < 0) {
            //没有找到头部数据
            return null;
        } else {
            byte bodyBytes[] = ByteBufferUtils.copyBytes(byteBuffer, bodyIndex);
            return new String(bodyBytes);
        }
    }
    /**
     * 获取数据内容
     *
     * @param lenght
     * @return
     */
    byte[] getBody(int index, int lenght) {
        //是否已经获取完整所有的数据
        byte[] bodyBytes = new byte[lenght];
        if (index < 0 || byteBuffer.position() < index + lenght) {
            //当前数据还没有接收完成
            return null;
        }
        for (int i = 0; i < bodyBytes.length; i++) {
            bodyBytes[i] = byteBuffer.get(index + i);
        }
        return bodyBytes;
    }
    /**
     * 这边处理了缓存数据粘包的情况,每次请求都需要吧当前完整的文件除去   以便于下次的返回
     * tempList用于存储多余的数据
     * contentList用于本次数据的存储(发送给订阅的数据)
     */
    byte[] geBody() {
        int len = 3 + 4 + 4 + ((byteBuffer.get(7) & 0xFF) * 256 * 256 * 256) + ((byteBuffer.get(8) & 0xFF) * 256 * 256) + ((byteBuffer.get(9) * 256) & 0xFF) + (byteBuffer.get(10) & 0xFf);
        byte[] bodyBytes = new byte[len];
        for (int i = 0; i < len; i++) {
            bodyBytes[i] = byteBuffer.get(i);
        }
        int endIndex = byteBuffer.position();
        byteBuffer.clear();
        for (int i = len; i < endIndex; i++) {
            byteBuffer.put(byteBuffer.get(i));
        }
        return bodyBytes;
    }
    /**
     * 移除可能存在的无效数据
     */
    void removeInVoidBytes() {
        int index = 0;
        boolean isMatch = false;
        for (; index < list.size() - head.length; index++) {
        for (; index < byteBuffer.position() - head.length; index++) {
            isMatch = true;
            for (int j = 0, k = 0; j < head.length; j++, k++) {
                if (head[j] != list.get(index + k)) {
                if (head[j] != byteBuffer.get(index + k)) {
                    isMatch = false;
                    break;
                }
@@ -116,159 +200,148 @@
        }
        if (0 < index && isMatch) {
            List<Byte> tempList = new ArrayList<Byte>();
            for (int i = index; i < list.size(); i++) {
                tempList.add(list.get(i));
            }
            list.clear();
            for (int i = 0; i < tempList.size(); i++) {
                list.add(tempList.get(i));
            int endIndex = byteBuffer.position();
            byteBuffer.clear();
            for (int i = index; i < endIndex; i++) {
                byteBuffer.put(byteBuffer.get(i));
            }
        }
    }
    /**
     * 移除到指定位置前面的数据
     *
     * @param position 指定位置
     */
    void remove(int position) {
        int endIndex = byteBuffer.position();
        byteBuffer.clear();
        for (int i = position; i < endIndex; i++) {
            byteBuffer.put(byteBuffer.get(i));
        }
    }
    int bytes2int(byte[] bytes) {
        int result = 0;
        if (bytes.length == 2) {
            int c = (bytes[0] & 0xff) << 8;
            int d = (bytes[1] & 0xff);
            result = c | d;
        } else if (bytes.length == 4) {
            return bytes[3] & 0xFF | //
                    (bytes[2] & 0xFF) << 8 | //
                    (bytes[1] & 0xFF) << 16 | //
                    (bytes[0] & 0xFF) << 24; //
        }
        return result;
    }
    public String byte2hex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        String tmp = null;
        for (byte b : bytes) {
            //将每个字节与0xFF进行与运算,然后转化为10进制,然后借助于Integer再转化为16进制
            tmp = Integer.toHexString(0xFF & b);
            if (tmp.length() == 1) {
                tmp = "0" + tmp;
            }
            sb.append(tmp + " ");
        }
        return sb.toString();
    }
//    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected synchronized LinkResponse decoder(Object msg, String ipaddress) throws Exception {
        if (msg instanceof byte[]) {
            bytes.addAll(ByteUtils.toByteList((byte[]) msg));
        if (msg == null || !(msg instanceof byte[])) {
            return null;
        }
        byte[] bytes = (byte[]) msg;
        try {
            byteBuffer.put(bytes);
        } catch (Exception e) {
            LogUtils.e("接收到数据异常:\r\n" + e.getMessage());
            byteBuffer.flip();
            byteBuffer.clear();
        }
        try {
            //如果多条命令打包在一条数据中,都需要处理完
            while (true) {
                initReceiveData(bytes);
                byte[] recevieBytes = ByteUtils.toByteArray(bytes);
                String data = new String(recevieBytes);
                removeInVoidBytes();//移除可能存在的无效数据
                String[] topMsgs = data.split("\r\n");
                //头部数据
                String header = getHeader();
                if (header == null) {
                    break;
                }
                String[] topMsgs = header.split("\r\n");
                String topic = getTopic(topMsgs);
                if (topic == null) {
                    break;
                }
                int lenght = getLenght(topMsgs);
                if (lenght <= 0) {
                    //头部数据还没有接收完成
                if (topic == null || lenght <= 0) {
                    //获取不到主题或者头部数据还没有接收完成
                    break;
                }
                int bodyIndex = getBodyIndex();
                //是否已经获取完整所有的数据
                byte[] body = new byte[lenght];
                int index = getDataIndex(bytes);
                if (bytes.size() < index + lenght) {
                byte[] body = getBody(bodyIndex, lenght);
                if (body == null) {
                    //当前数据还没有接收完成
                    break;
                }
                //复制出body数据
                System.arraycopy(recevieBytes, index, body, 0, body.length);
                //保留剩余的数据,以次用
                bytes.clear();
                for (int i = index + lenght; i < recevieBytes.length; i++) {
                    bytes.add(recevieBytes[i]);
                remove(bodyIndex + lenght);
                if (topic.contains("heartbeat_reply")) {
//                    if (packet.getSocket() != null) {
//                        packet.getSocket().setSoTimeout(10 * 1000);
//                    }
                    continue;
                }
                LinkResponse response = new LinkResponse();
                response.setSource_ipAddress(ipaddress);
                response.setTopic(topic);
                if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
                if (encrypt(body)) {
                    //需要解密
                    byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
                    if (bodyBytes != null) {
                        body = bodyBytes;
                        response.setData(new String(bodyBytes, StandardCharsets.UTF_8));
                    } else {
                        try {
                            //之前的版本这块是明文的
                            if (!topic.contains("heartbeat_reply")) {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                                    LogUtils.e("解密失败,数据内容是:\r\n" + Base64.encodeToString(body, Base64.NO_WRAP));
                                else {
                                    LogUtils.e("解密失败,数据内容是:\r\n" + new String(body, "utf-8"));
                                }
                            }
                        } catch (Exception e) {
                        }
                        LogUtils.e("解密失败\r\n" + topic);
                        response.setData(new String(body, "utf-8"));
                        continue;
                    }
                } else {
                    response.setData(new String(body, "utf-8"));
                }
                String bodyString = new String(body, "utf-8");
                response.setData(bodyString);
                LogUtils.i("接收到数据:" + response.getTopic() + "\r\n" + response.getData());
                LogUtils.i("本地接收到数据:\r\n" + response.getTopic() + "\r\n" + response.getData() + "\r\n" + response.getData().length());
                String updateLocalSecret = String.format(TopicConstant.LINK_BROADCAST, HDLLinkConfig.getInstance().getGatewayId());
                String deleteNetwork = "";
                if (HDLLinkConfig.getInstance().getDeviceInfoBean() != null) {
                    deleteNetwork = String.format(TopicConstant.DELETE_NOTIFY, HDLLinkConfig.getInstance().getDeviceInfoBean().getOID());
                }
                if (response.getTopic().equals("/user/all/custom/gateway/search")) {
                    HDLAuthSocket.getInstance().UploadGatewayInfo(new HDLLinkCallBack() {
                        @Override
                        public void onSuccess(String msg) {
                            LogUtils.i("UploadGatewayInfo onSucceed");
                        }
                        @Override
                        public void onError(HDLLinkException e) {
                            LogUtils.i("UploadGatewayInfo onError");
                        }
                    });
                } else if (response.getTopic().equals(updateLocalSecret) || response.getTopic().equals(TopicConstant.LINK_BROADCAST)) {
                    try {
                        DeviceInfoResponse deviceInfoResponse = GsonConvert.getGson().fromJson(response.getData(), new TypeToken<DeviceInfoResponse>() {
                        }.getType());
                        if (!TextUtils.isEmpty(deviceInfoResponse.getObjects().getLocalSecret())) {
                            byte[] baseBytes = Base64.decode(deviceInfoResponse.getObjects().getLocalSecret(), Base64.NO_WRAP);
                            String mackey = "";
                            if (!TextUtils.isEmpty(SPUtils.getString("auth_mackey_key", ""))) {
                                mackey = SPUtils.getString("auth_mackey_key", "");
                                byte[] bodyBytes = AesUtil.aesDecrypt(baseBytes, mackey.substring(mackey.length() - 16));
                                String localSecret = new String(bodyBytes, "utf-8");
                                Log.d("panlili", "更新密钥----->localSecret= " + localSecret);
                                HDLLinkConfig.getInstance().setLocalSecret(localSecret);
                            }
                        }
                    } catch (Exception e) {
                        LogUtils.i("LinkMessageDecoder.java:getLocalSecret----->e= " + e.getMessage());
                    }
                } else if (response.getTopic().equals(deleteNetwork)) {
                    try {
                        DeviceDeleteResponse deviceDeleteResponse = GsonConvert.getGson().fromJson(response.getData(), new TypeToken<DeviceDeleteResponse>() {
                        }.getType());
                        HDLSocket.getInstance().deleteNetwork(deviceDeleteResponse.getObjects().get(0).getOID(), new HDLLinkCallBack() {
                            @Override
                            public void onSuccess(String msg) {
                                LogUtils.i("deleteNetwork onSucceed");
                                if (HDLLink.getInstance().listener != null) {
                                    HDLLink.getInstance().listener.onSuccess(msg);
                                }
                            }
                            @Override
                            public void onError(HDLLinkException e) {
                                LogUtils.i("deleteNetwork onError");
                                if (HDLLink.getInstance().listener != null) {
                                    HDLLink.getInstance().listener.onFailure();
                                }
                            }
                        });
                    } catch (Exception e) {
                        LogUtils.i("LinkMessageDecoder.java:deleteNetwork----->e= " + e.getMessage());
                    }
                }
                //非正常数据,返回
                if (!((bodyString.startsWith("{") && bodyString.endsWith("}"))
                        || (bodyString.startsWith("[") && bodyString.endsWith("]")))) {
                    continue;
                }
                //解析完成,topic发送一次
                EventDispatcher.getInstance().post(response.getTopic(), response);
            }
            return null;
        } catch (Exception ee) {
            LogUtils.e("处理接收的数据异常:\r\n" + ee.getMessage());
        }
        return null;
    }
    //是否加密
    private boolean encrypt(byte[] bytes) {
        if (bytes[0] == '{' && bytes[bytes.length - 1] == '}' || (bytes[0] == '[' && bytes[bytes.length - 1] == ']')) {
            return false;
        }
        return true;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -148,19 +148,32 @@
        EventDispatcher.getInstance().register(TopicConstant.GATEWAY_AUTH_BROADCAST, new EventListener() {
            @Override
            public void onMessage(Object msg) {
                LogUtils.i("收到网关认证信息: ");
                NetworkAccessBroadcastResponse bean = getNetworkAccessBroadcastResponse(msg);
                if (bean != null) {
                    //移除监听
                    EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST);
                    LogUtils.i("网关入网广播IP: " + bean.getIPAddress());
                    HDLLinkConfig.getInstance().setIpAddress(bean.getIPAddress());
                    String ipStr = bean.getIPAddress();
                    if (!TextUtils.isEmpty(ipStr)) {
                        sendAuthenticateRequest(ipStr, request, callBack);
                try {
                    LogUtils.i("收到网关认证信息: ");
                    NetworkAccessBroadcastResponse bean = getNetworkAccessBroadcastResponse(msg);
                    if (bean != null) {
                        LogUtils.i("网关入网广播IP: " + bean.getIPAddress());
                        if (!TextUtils.isEmpty(bean.getSlave_mac())) {
                            if (!bean.getSlave_mac().equals(request.getObjects().getDeviceMAC())) {
                                LogUtils.i("入网验证的mac和本机不一样,请求的MAC是" + bean.getSlave_mac() + " 本机的是" + request.getObjects().getDeviceMAC());
                                return;
                            }
                        }
                        //移除监听
                        EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST);
                        HDLLinkConfig.getInstance().setIpAddress(bean.getIPAddress());
                        if (!TextUtils.isEmpty(bean.getOID())) {
                            HDLLinkConfig.getInstance().setParentOid(bean.getOID());
                        }
                        String ipStr = bean.getIPAddress();
                        if (!TextUtils.isEmpty(ipStr)) {
                            sendAuthenticateRequest(ipStr, request, callBack);
                        }
                    }
                }
                } catch (Exception e) {
                    LogUtils.e("入网验证异常", e.getMessage());
                }
            }
        });
    }
@@ -186,6 +199,7 @@
        final GatewayInfoRequest request = new GatewayInfoRequest();
        AuthenticateRequest.AuthenticateDeviceInfoBean authenticateDeviceInfoBean = HDLLinkConfig.getInstance().getDeviceInfoBean();
        if (authenticateDeviceInfoBean == null) return;
        request.setDevice_model(authenticateDeviceInfoBean.getDeviceModel());
        request.setDevice_mac(authenticateDeviceInfoBean.getDeviceMAC());
        request.setDevice_name(authenticateDeviceInfoBean.getDeviceName());
@@ -197,7 +211,9 @@
        if (authenticateDeviceInfoBean.getSupplier() == null) {
            AuthenticateRequest.RequestBean requestBean = HDLLinkConfig.getInstance().getRequestBean();
            request.setSupplier(requestBean.getSupplier());
            if (requestBean != null) {
                request.setSupplier(requestBean.getSupplier());
            }
        }
        request.setHw_version(authenticateDeviceInfoBean.getHw_version());
@@ -205,6 +221,7 @@
        request.setIp_address(authenticateDeviceInfoBean.getIPAddress());
        request.setMaster("false");
        request.setLocalEncrypt(false);
        request.setHomeId(HDLLinkConfig.getInstance().getHomeId());
        data.setObjects(request);
@@ -213,21 +230,7 @@
                GsonConvert.getGson().toJson(data));
        String ip = IpUtils.getBroadcastAddress();
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
            @Override
            public void onSucceed(Object msg) {
                if (callBack == null) return;
                callBack.onSuccess("上报成功");
                LogUtils.i("UploadGatewayInfo onSucceed = " + msg);
            }
            @Override
            public void onFailure() {
                if (callBack == null) return;
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_UPLOAD_GATEWAYINFO_FAILURE_ERROR));
                LogUtils.i("UploadGatewayInfo onFailure");
            }
        });
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, null);
    }
@@ -258,16 +261,21 @@
                            String localSecret = "";
                            String gatewayId = "";
                            String ipAddress = "";
                            String homeId = "";
                            if (bean.getAuth() != null) {
                                localSecret = bean.getAuth().getLocalSecret();
                            }
                            if (bean.getObjects() != null) {
                                gatewayId = bean.getObjects().getGatewayID();
                                ipAddress = bean.getObjects().getIPAddress();
                                homeId = bean.getObjects().getHomeId();
                            }
                            if (ipAddress == null) {
                                ipAddress = bean.getIp_address();
                            }
                            if (!TextUtils.isEmpty(homeId)) {
                                HDLLinkConfig.getInstance().setHomeId(homeId);
                            }
                            HDLLinkConfig.getInstance().setAuthBean(request.getAuth());
                            //判断网关是否已经注册到云端
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -24,6 +24,7 @@
import com.hdl.sdk.connect.bean.request.FunctionAttributeRequest;
import com.hdl.sdk.connect.bean.request.ListOidRequest;
import com.hdl.sdk.connect.bean.request.ListOidRequest2;
import com.hdl.sdk.connect.bean.request.ListSidRequest;
import com.hdl.sdk.connect.bean.request.ListUploadRequest;
import com.hdl.sdk.connect.bean.request.PropertyReadRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalCodeResponse;
@@ -113,7 +114,7 @@
                        }
                        BroadcastRequest request = new BroadcastRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), "200");
                        HDLAuthSocket.getInstance().udpSendMsg(TopicConstant.BROADCAST, GsonConvert.getGson().toJson(request), true, new HDLLinkResponseCallBack() {
//                            @RequiresApi(api = Build.VERSION_CODES.O)
                            //                            @RequiresApi(api = Build.VERSION_CODES.O)
                            @Override
                            public void onSuccess(LinkResponse msg) {
                                String data = msg.getData();
@@ -649,12 +650,62 @@
            data.setId(IdUtils.getUUId());
            data.setTime_stamp(time);
            //2023.10.18修改,上报oid列表增加parentOid
            if (request!=null && !TextUtils.isEmpty(HDLLinkConfig.getInstance().getParentOid())) {
                request.setParentOid(HDLLinkConfig.getInstance().getParentOid());
            }
            List<ListUploadRequest> list = new ArrayList<>();
            list.add(request);
            data.setObjects(list);
            String topic = String.format(TopicConstant.LIST_UPLOAD, getGatewayId());
            LinkRequest message = new LinkRequest(topic,
                    GsonConvert.getGson().toJson(data));
            String replyTopic = topic + "_reply";
            try {
                sendMsg(message.getSendBytes(), replyTopic, callBack, new SendListener() {
                    @Override
                    public void onSucceed() {
                    }
                    @Override
                    public void onError() {
                        if (callBack != null) {
                            callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
                        }
                    }
                });
            } catch (Exception e) {
                if (callBack != null) {
                    callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
                }
            }
        } else {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
            }
        }
    }
    /**
     * 上报Sid列表
     *
     * @param requestList sid列表
     * @param callBack    回调
     */
    public void UploadSidList(List<ListSidRequest> requestList, HDLLinkCallBack callBack) {
        if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) {
            String time = String.valueOf(System.currentTimeMillis());
            final BaseLocalResponse<List<ListSidRequest>> data = new BaseLocalResponse<>();
            data.setId(IdUtils.getUUId());
            data.setTime_stamp(time);
            data.setObjects(requestList);
            String topic = String.format(TopicConstant.LIST_SID_UPLOAD, getGatewayId());
            LinkRequest message = new LinkRequest(topic,
                    GsonConvert.getGson().toJson(data));
@@ -890,14 +941,13 @@
//        String replyTopic = topic + "_reply";
        try {
            sendMsg(message.getSendBytes(), topic, callBack, new SendListener() {
            sendMsg(message.getSendBytes(), topic, null, new SendListener() {
                @Override
                public void onSucceed() {
                    HDLLinkConfig.getInstance().clearConfig();
                    if (callBack == null) return;
                    try {
                        callBack.onSuccess("退网成功");
                        HDLLinkConfig.getInstance().clearConfig();
                    } catch (Exception e) {
                        callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR));
                    }
@@ -936,7 +986,11 @@
    public void tcpSendMsg(String topic, String bodyStr, HDLLinkCallBack callBack) {
        try {
            LinkRequest message = new LinkRequest(topic, bodyStr);
            if (topic != null && topic.endsWith("_reply")) {
                callBack = null;
            }
            String replyTopic = topic + "_reply";
            HDLLinkCallBack finalCallBack = callBack;
            sendMsg(message.getSendBytes(), replyTopic, callBack, new SendListener() {
                @Override
                public void onSucceed() {
@@ -945,8 +999,8 @@
                @Override
                public void onError() {
                    if (callBack != null) {
                        callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
                    if (finalCallBack != null) {
                        finalCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
                    }
                }
            });
@@ -1005,7 +1059,7 @@
                threadPool.scheduleWithFixedDelay(new Runnable() {
                    @Override
                    public void run() {
                        if (sendCount.get() < 3) {
                        if (sendCount.get() < 0) {
                            sendCount.set(sendCount.get() + 1);
                            getTcp().sendMsg(data);
                        } else {
@@ -1055,4 +1109,56 @@
    }
    /**
     * 回复网关配置命令
     *
     * @param mac_Oid_GatewayId
     * @param msgId             消息Id
     * @param callBack
     */
    public void gatewayRemoteEditReply(String mac_Oid_GatewayId, String msgId, HDLLinkCallBack callBack) {
        if (TextUtils.isEmpty(mac_Oid_GatewayId)) {
            callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR));
        }
        String time = String.valueOf(System.currentTimeMillis());
        final BaseLocalCodeResponse<List<String>> data = new BaseLocalCodeResponse<>();
        data.setId(msgId);
        data.setTime_stamp(time);
        data.setCode("0");
        String topic = String.format(TopicConstant.GATEWAY_EDIT_REMOTE_REPLY, mac_Oid_GatewayId);
        LinkRequest message = new LinkRequest(topic,
                GsonConvert.getGson().toJson(data));
        try {
            sendMsg(message.getSendBytes(), topic, callBack, new SendListener() {
                @Override
                public void onSucceed() {
                    if (callBack == null) return;
                    try {
                        callBack.onSuccess("退网成功");
                        HDLLinkConfig.getInstance().clearConfig();
                    } catch (Exception e) {
                        callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR));
                    }
                }
                @Override
                public void onError() {
                    if (callBack != null) {
                        callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
                    }
                }
            });
        } catch (Exception e) {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR));
            }
        }
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -91,7 +91,7 @@
     * 注册监听
     */
    void registerListener() {
        if (!TextUtils.isEmpty(observeTopic)) {
        if (listener != null && !TextUtils.isEmpty(observeTopic)) {
            EventDispatcher.getInstance().register(observeTopic, eventListener);
//            LogUtils.i("HdlSocketHelper", "register event");
        }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java
New file
@@ -0,0 +1,37 @@
package com.hdl.sdk.connect.utils;
import java.nio.ByteBuffer;
/**
 * Created by hxb on 2022/8/3.
 *
 */
public class ByteBufferUtils {
    /**
     * 获取ByteBuffer指定位置数据
     *
     * @param byteBuffer 源对象
     * @param length 指定长度
     * @return 根据长度生成的数组
     */
    public static byte[] copyBytes(ByteBuffer byteBuffer, int length) {
        return copyBytes(byteBuffer,0,length);
    }
    /**
     * 复制指定位置的数据
     * @param byteBuffer
     * @param index
     * @param length
     * @return
     */
    public static byte[] copyBytes(ByteBuffer byteBuffer, int index,int length) {
        byte[] bytes = new byte[length];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = byteBuffer.get(index + i);
        }
        return bytes;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/socket/client/UdpClient.java
@@ -29,7 +29,7 @@
    /**
     * 当前socket
     */
    private  DatagramSocket mSocket;
    private DatagramSocket mSocket;
    /**
     * 接收数据包
@@ -57,11 +57,12 @@
    /**
     * 初始化参数
     * @param ipAddress 本地监听端口
     * @param port 本地监听端口
     *
     * @param ipAddress     本地监听端口
     * @param port          本地监听端口
     * @param socketOptions
     */
    private UdpClient(String ipAddress,int port, UdpSocketOptions socketOptions) {
    private UdpClient(String ipAddress, int port, UdpSocketOptions socketOptions) {
        this.ipAddress = ipAddress;
        this.port = port;
        this.socketOptions = socketOptions;
@@ -71,8 +72,9 @@
    /**
     * 初始化参数
     *
     * @param ipAddress 本地监听IP地址
     * @param port 本地监听端口
     * @param port      本地监听端口
     * @param options
     * @return
     */
@@ -82,7 +84,8 @@
    /**
     * 初始化参数
     * @param port 本地监听端口
     *
     * @param port    本地监听端口
     * @param options
     * @return
     */
@@ -100,8 +103,8 @@
            }
            if (TextUtils.isEmpty(ipAddress)) {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(port));
            }else {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(ipAddress,port));
            } else {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(ipAddress, port));
            }
            mSocket.setBroadcast(true);
//            mSocket.setReuseAddress(true);
@@ -156,7 +159,7 @@
            if (handleMessage != null) {
                byte[] data = new byte[receivePacket.getLength()];
                System.arraycopy(receivePacket.getData(), 0, data, 0, data.length);
                handleMessage.read(data,receivePacket.getAddress().getHostAddress());
                handleMessage.read(data, receivePacket.getAddress().getHostAddress());
            }
        } catch (Exception e) {
@@ -166,11 +169,12 @@
    @Override
    public void sendMsg(String ipAddress,int port, byte[] msg) throws Exception {
    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);
        if (sendPacket == null) return;
        mSocket.send(sendPacket);
    }
}
HDLSDK_DEMO/app/build.gradle
@@ -38,7 +38,8 @@
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'
//    implementation 'com.google.code.gson:gson:2.8.8'
//    implementation project(path: ':hdl-connect')
    implementation files('libs\\com.hdl.sdk-v1.1.4.aar')
    implementation files('libs\\com.hdl.sdk-v1.1.6.aar')
}
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.1.4.aar
Binary files differ
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.1.6.aar
Binary files differ
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -1,8 +1,10 @@
package com.hdl.hdlsdk;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -15,7 +17,6 @@
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -28,15 +29,19 @@
import com.hdl.sdk.common.event.DeleteNetworkListener;
import com.hdl.sdk.common.event.EventListener;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.AllTopicManagerUtils;
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.LinkResponse;
import com.hdl.sdk.connect.bean.request.AttributesRequest;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.ListSidRequest;
import com.hdl.sdk.connect.bean.request.ListUploadRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.bean.response.DeviceInfoResponse;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
@@ -68,24 +73,6 @@
    protected void onDestroy() {
        super.onDestroy();
        removeAllTopicsListener();
    }
    void initDeviceInfo() {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("音乐播放器");//设备名字
        infoBean.setDeviceModel("MCLog.431");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.1.1");
        infoBean.setIPAddress("192.168.1.103");
        infoBean.setGateway_type("screen.touch");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /*void applyDeviceSecret() {
@@ -128,66 +115,33 @@
            }
        });
    }*/
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
    void checkAppVersion() {
        tv.setText("开始检测更新...");
        responseTv.setText("");
        //认证提交参数准备
//
//        //测试服务器
//        String spkStr = "music.standard";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.touch";//产品spk
//        String macStr = "AA00000000000100";//设备唯一MAC地址
        String macStr = editText.getText().toString();//设备唯一MAC地址
//        String secret = "e186beeb7974998e";//通过spk和mac提交云端认证后分配的secret
//        //正式服务器
        String appKey = "i8hR07jzrIS";//appkey
        String appSecret = "BmnJ8RWTtaVEBk24zPPF4UMwfYu0lAWU";//appsecret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
//        HDLLinkConfig.getInstance().setCurrentGateway(infoBean);
        String appCode = "1697150870315999233";//appCode
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
//        HDLLinkConfig.getInstance().setRequestBean(requestBean);
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        HDLLinkConfig.getInstance().setAuthBean(authbean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
        HDLLink.getInstance().checkAppVersion(this, appKey, appSecret, getAppVersionName(this), appCode, new CheckAppVersionListener() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败" + e.getCode());
                responseTv.setText(e.getMsg());
                Log.e(TAG, "onError: 认证失败 " + e.getCode());
            public void onSuccess(UpdateInfo info) {
                tv.setText("有新更新");
                responseTv.setText(info.toString());
            }
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
                localSecret.setText("密钥:" + HDLLinkConfig.getInstance().getLocalSecret());
            public void onError(HDLException e) {
                tv.setText("检测更新失败");
                responseTv.setText(e.getMsg());
            }
        });
    }
    }*/
    public void UploadDeviceAuth(String mac, String result, String message, String auth_code) {
        //将认证结果上报给网关
@@ -235,6 +189,8 @@
            }
        });
        UploadSidList();
        ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
            public void onActivityResult(Map<String, Boolean> result) {
@@ -261,6 +217,7 @@
        beans.add(new DemoBean("UDP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("TCP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("退网"));
        beans.add(new DemoBean("检测更新"));
        demoAdapter = new DemoAdapter(beans);
        rv.setAdapter(demoAdapter);
@@ -313,7 +270,7 @@
                        break;
                    case 9:
                        //场景控制
                        controlScene();
                        getScene();
                        break;
                    case 10:
                        //功能列表
@@ -338,6 +295,10 @@
                    case 15:
                        //退网
                        deleteNetwork();
                        break;
                    case 16:
                        //检测更新
//                        checkAppVersion();
                        break;
                }
            }
@@ -371,7 +332,7 @@
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse) msg;
                if ("/user/all/custom/gateway/broadcast_reply".equals(response.getTopic())){
                if ("/user/all/custom/gateway/broadcast_reply".equals(response.getTopic())) {
                    localSecret.setText("密钥:" + HDLLinkConfig.getInstance().getLocalSecret());
                }
            }
@@ -422,6 +383,75 @@
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    void initDeviceInfo()
    {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("魔镜");//设备名字
        infoBean.setDeviceModel("HDLSDK");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.1.1");
        infoBean.setIPAddress("192.168.1.116");
        infoBean.setGateway_type("screen.touch");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
        //认证提交参数准备
//        测试服务
//        String spkStr = "ir.module";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.touch";//产品spk
        String macStr = "f2c5d8bad48f";//设备唯一MAC地址
        String secret = "7728691efecc3853";//通过spk和mac提交云端认证后分配的secret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败");
                responseTv.setText(e.getMsg());
                Log.i("TAG", "onError: 认证失败");
            }
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
            }
        });
    }
    String stringToMD5(String text) {
        byte[] hash;
@@ -575,6 +605,7 @@
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
                Log.d("panlili", "MainActivity.java:getSceneList-----> " + msg);
            }
            @Override
@@ -586,6 +617,30 @@
    //场景列表
    // {"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 getScene() {
        tv.setText("场景读取");
        responseTv.setText("");
        //场景sid列表,支持批量读取
        List<String> sids = new ArrayList<>();
        sids.add("0201034C50B53F0A0A0100011100");
        sids.add("0201037F50B53F0A0A0100021100");
        HDLLink.getInstance().getScene(sids, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * 控制场景
@@ -758,4 +813,66 @@
            }
        });
    }
    private void UploadSidList() {
        tv.setText("上报Sid列表...");
        responseTv.setText("");
        //1.设置设备信息
        AuthenticateRequest.AuthenticateDeviceInfoBean authenticateDeviceInfoBean = HDLLinkConfig.getInstance().getDeviceInfoBean();
        ListSidRequest request = new ListSidRequest();
        request.setOid(authenticateDeviceInfoBean.getOID());
        request.setName("sid名称");
        request.setOmodel(authenticateDeviceInfoBean.getDeviceModel());
        request.setSid("12345678");//当前sid的
        request.setSpk("light.switch");//当前spk名称,根据实际设备来定义
        request.setFrom(authenticateDeviceInfoBean.getOID());//来自哪个网关,如果时Link网络设备,则填自身oid;如果是驱动则不需要此字段
        AttributesRequest attributes = new AttributesRequest();
        attributes.setKey("on_off");
        attributes.setData_type("string");
        List<Object> valueList=new ArrayList<>();
        valueList.add("on");
        valueList.add("off");
        attributes.setValue(valueList);
        //添加支持的属性列表
        List<AttributesRequest> attributesList = new ArrayList<>();
        request.setAttributes(attributesList);
        List<ListSidRequest> sidRequestList = new ArrayList<>();
        sidRequestList.add(request);
        HDLLink.getInstance().UploadSidList(sidRequestList, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException error) {
                tv.setText(error.getMsg());
            }
            @Override
            public void onSuccess(String data) {
                tv.setText("上报sid列表成功");
                responseTv.setText(data);
            }
        });
    }
    /**
     * 获取APP版本
     *
     * @param context
     * @return
     */
    public static String getAppVersionName(Context context) {
        String versionName = "0";
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            versionName = packageInfo.versionName;
            if (TextUtils.isEmpty(versionName)) {
                versionName = "0";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return versionName;
    }
}