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_StoreBinary 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.aarBinary files differ
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.1.6.aarBinary 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; } }