HDLSDK.zipBinary files differ
HDLSDK/app/build.gradle
@@ -6,7 +6,7 @@ compileSdk 31 defaultConfig { applicationId "com.hdl.hdlsdk" applicationId "com.hdl.hdlsdk1" minSdk 21 targetSdk 31 versionCode 1 HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -4,12 +4,14 @@ 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; import android.Manifest; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -27,6 +29,7 @@ import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.IdUtils; import com.hdl.sdk.common.utils.IpUtils; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.gson.GsonConvert; import com.hdl.sdk.connect.HDLLink; import com.hdl.sdk.connect.bean.LinkRequest; @@ -45,15 +48,18 @@ import com.hdl.sdk.connect.protocol.LinkMessageEncoder; import com.hdl.sdk.socket.SocketOptions; import com.hdl.sdk.socket.codec.MessagePipeLine; import java.util.Base64; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.Map; import static com.hdl.sdk.common.config.TopicConstant.GATEWAY_SEARCH_REPLY; import static java.util.Base64.*; public class MainActivity extends AppCompatActivity { @@ -71,7 +77,12 @@ super.onDestroy(); removeAllTopicsListener(); } void init() { // HDLLinkConfig.getInstance().setLocalSecret("7d04c4e3c2b7d600"); // HDLLinkConfig.getInstance().setGatewayId("1473119283609321473"); // HDLLinkConfig.getInstance().setLocalEncrypt(true); } @RequiresApi(api = Build.VERSION_CODES.O) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -81,8 +92,9 @@ rv = findViewById(R.id.rv); rv.setLayoutManager(new LinearLayoutManager(this)); init(); checkIfCertified(); initDeviceInfo(); initDeviceInfo();//初始化基本信息,非常重要,认证时要用 registerAllTopicsListener(); ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { @@ -254,18 +266,18 @@ void initDeviceInfo() { AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean(); infoBean.setDeviceMAC("123456789"); infoBean.setIPMAC("12345678900"); infoBean.setDeviceMAC("AA000000000000AF"); infoBean.setIPMAC("AA000000000000AF"); infoBean.setDeviceName("音乐播放器");//设备名字 infoBean.setDeviceModel("MCLog.431");//设备型号 infoBean.setAccessMode("WIFI"); infoBean.setIPGateway("192.168.88.1"); infoBean.setIPAddress("192.168.88.100"); infoBean.setIPGateway("192.168.1.1"); infoBean.setIPAddress("192.168.1.102"); infoBean.setGateway_type("music.standard"); infoBean.setHw_version("HW2.0"); infoBean.setFw_version("Fw1.0"); infoBean.setOID("010105000000FE08"); infoBean.setSid("010105000000FE08110100000000"); infoBean.setOID("010105000000FE10");//每个设备oid都要不一样 infoBean.setSid("110105000000FE08110100000000");//每个设备的sid都要不一样 HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean); } @@ -276,12 +288,12 @@ tv.setText("开始入网认证..."); //认证提交参数准备 // //测试服务 // 测试服务 // String spkStr = "ir.module";//产品spk // String macStr = "AA000000000000BB";//设备唯一MAC地址 // String secret = "87ae414b7a853f65";//通过spk和mac提交云端认证后分配的secret // String macStr = "AA000000000000AF";//设备唯一MAC地址 // String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret //正式服务器 // 正式服务器 String spkStr = "screen.mirror";//产品spk String macStr = "AA000000000000AC";//设备唯一MAC地址 String secret = "ee62124c151b737c";//通过spk和mac提交云端认证后分配的secret @@ -289,35 +301,20 @@ 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("raysgem"); requestBean.setSupplier("WISE"); requestBean.setFirmwareVersion(versionString); requestBean.setHardwareModel("1956F"); AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean(); authbean.setSpk(spkStr); authbean.setMACKey(mac_key); authbean.setRequest(requestBean); //2.设置设备信息 AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean(); infoBean.setDeviceMAC(macStr); infoBean.setIPMAC(macStr); infoBean.setDeviceName("红外宝");//设备名字 infoBean.setDeviceModel("HDL");// infoBean.setAccessMode("WIFI"); infoBean.setIPGateway("192.168.88.1"); infoBean.setIPAddress(IpUtils.getIP(this));//根据真实的IP地址填写 infoBean.setOID("010105000000FE08"); infoBean.setSid("010105000000FE08110100000000"); infoBean.setHw_version("1.0"); infoBean.setFw_version("1.0"); // infoBean.set AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, infoBean, 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) { HDLSDK/hdl-common/build.gradle
@@ -9,8 +9,8 @@ minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion versionCode 2 versionName "1.0.3" versionName "1.0.10" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/HDLSdk.java
@@ -11,6 +11,16 @@ private Context context; /** * 获取当前版本 * @return */ public String getVersion() { return version; } private String version="1.0.8"; private HDLSdk() { } @@ -24,6 +34,7 @@ public void init(Context context) { this.context = context.getApplicationContext(); LogUtils.i("Version:" + version); } public Context getContext() { HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java
@@ -87,4 +87,12 @@ */ public static final String BROADCAST_REPLY="/user/all/custom/gateway/broadcast_reply"; /** * 心跳检测 */ public static final String HEARTBEAT="/user/%s/custom/gateway/heartbeat"; /** * 心跳检测回复 */ public static final String HEARTBEAT_REPLY="/user/%s/custom/gateway/heartbeat_reply"; } HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventDispatcher.java
@@ -27,7 +27,7 @@ private static final int MAIN_TYPE = 0; private static final int IO_TYPE = 1; private static final ExecutorService ioThread = ThreadToolUtils.getInstance().newFixedThreadPool(2); private static final ExecutorService ioThread = ThreadToolUtils.getInstance().newFixedThreadPool(3); private EventDispatcher() { } @@ -63,43 +63,48 @@ } public synchronized void remove(Object tag) { ioThread.execute(new Runnable() { @Override public void run() { try { if (EVENT.containsKey(tag)) { List<EventListener> list = EVENT.get(tag); for (EventListener eventListener : list) { TYPE.remove(eventListener); try { ioThread.execute(new Runnable() { @Override public void run() { try { if (EVENT.containsKey(tag)) { List<EventListener> list = EVENT.get(tag); for (EventListener eventListener : list) { TYPE.remove(eventListener); } EVENT.remove(tag); } EVENT.remove(tag); } catch (Exception ignored) { } } catch (Exception ignored) { } } }); }); }catch (Exception e){} } public synchronized void remove(Object tag, EventListener listener) { ioThread.execute(new Runnable() { @Override public void run() { try { if (EVENT.containsKey(tag)) { List<EventListener> ev = EVENT.get(tag); if (ev != null && !ev.isEmpty()) { TYPE.remove(listener); ev.remove(listener); try { ioThread.execute(new Runnable() { @Override public void run() { try { if (EVENT.containsKey(tag)) { List<EventListener> ev = EVENT.get(tag); if (ev != null && !ev.isEmpty()) { TYPE.remove(listener); ev.remove(listener); } } } catch (Exception ignored) { } } catch (Exception ignored) { } } }); }); }catch (Exception e){} } @@ -150,20 +155,22 @@ * @param listener */ public synchronized void removeAllTopicsListener(EventListener listener) { ioThread.execute(new Runnable() { @Override public void run() { try { if (ALL_TOPICS_EVENT != null && !ALL_TOPICS_EVENT.isEmpty()) { TYPE.remove(listener); ALL_TOPICS_EVENT.remove(listener); try { ioThread.execute(new Runnable() { @Override public void run() { try { if (ALL_TOPICS_EVENT != null && !ALL_TOPICS_EVENT.isEmpty()) { TYPE.remove(listener); ALL_TOPICS_EVENT.remove(listener); } } catch (Exception ignored) { } } catch (Exception ignored) { } } }); }); }catch (Exception e){} } public synchronized void clear() { HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IpUtils.java
@@ -19,21 +19,21 @@ * @return 广播地址 */ public static String getBroadcastAddress() { try { for (Enumeration<NetworkInterface> niEnum = NetworkInterface.getNetworkInterfaces(); niEnum.hasMoreElements(); ) { NetworkInterface ni = niEnum.nextElement(); if (!ni.isLoopback()) { for (InterfaceAddress interfaceAddress : ni.getInterfaceAddresses()) { if (interfaceAddress.getBroadcast() != null) { return interfaceAddress.getBroadcast().toString().substring(1); } } } } } catch (SocketException e) { e.printStackTrace(); } // try { // for (Enumeration<NetworkInterface> niEnum = NetworkInterface.getNetworkInterfaces(); // niEnum.hasMoreElements(); ) { // NetworkInterface ni = niEnum.nextElement(); // if (!ni.isLoopback()) { // for (InterfaceAddress interfaceAddress : ni.getInterfaceAddresses()) { // if (interfaceAddress.getBroadcast() != null) { // return interfaceAddress.getBroadcast().toString().substring(1); // } // } // } // } // } catch (SocketException e) { // e.printStackTrace(); // } return "255.255.255.255"; } HDLSDK/hdl-connect/build.gradle
@@ -9,7 +9,7 @@ minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion versionCode 2 versionName "1.0.3" versionName "1.0.10" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" @@ -44,4 +44,4 @@ // //加密 // implementation 'cn.hutool:hutool-all:5.6.5' // implementation 'org.bouncycastle:bcprov-jdk15on:1.60' } } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java
@@ -1,5 +1,6 @@ package com.hdl.sdk.connect; import com.hdl.sdk.common.utils.ThreadToolUtils; import com.hdl.sdk.connect.bean.request.DeviceControlRequest; import com.hdl.sdk.connect.callback.HDLLinkCallBack; import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack; @@ -11,6 +12,7 @@ import com.hdl.sdk.connect.socket.HDLSocket; import java.util.List; import java.util.concurrent.TimeUnit; /** * Created by jlchen on 11/15/21. @@ -32,6 +34,12 @@ synchronized (HDLLink.class) { if (instance == null) { instance = new HDLLink(); // ThreadToolUtils.getInstance().newScheduledThreadPool(1).scheduleWithFixedDelay(new Runnable() { // @Override // public void run() { ////定期搜索网关,后面看有必要再做 // } // },0,10, TimeUnit.SECONDS); } } } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java
@@ -88,11 +88,13 @@ String headString = "Topic:" + getTopic() + "\r\n" + "Length:" + dataBytes.length + "\r\n" + "\r\n"; byte[] headBytes = headString.getBytes("utf-8"); byte[] sendBytes = ByteUtils.concatBytes(headBytes, dataBytes); LogUtils.i(headString + "\r\n" + data); LogUtils.i("发送数据:\r\n" + headString + "\r\n" + data); return sendBytes; } else { return this.toString().getBytes("utf-8"); String sendString = this.toString(); LogUtils.i("发送数据:\r\n" + sendString); return sendString.getBytes("utf-8"); } } catch (Exception e) { HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkResponse.java
@@ -17,6 +17,16 @@ private String data; private int length; public String getSource_ipAddress() { return source_ipAddress; } public void setSource_ipAddress(String source_ipAddress) { this.source_ipAddress = source_ipAddress; } public String source_ipAddress; public String getTopic() { return topic; } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java
@@ -3,6 +3,7 @@ import android.text.TextUtils; import com.hdl.sdk.common.config.TopicConstant; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.SPUtils; import com.hdl.sdk.connect.bean.request.AuthenticateRequest; import com.hdl.sdk.connect.bean.response.GatewaySearchBean; @@ -22,7 +23,6 @@ private String localSecret;//本地加密密钥 private String gatewayId; private String ipAddress; private boolean isLocalEncrypt;//网关是否需要加密通讯 private GatewaySearchBean currentGateway;//当前网关 private AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean;//当前设备基本信息 @@ -56,7 +56,6 @@ this.gatewayId = ""; this.ipAddress = ""; this.localSecret = ""; this.isLocalEncrypt = false; SPUtils.remove(AUTHENTICATE_LS_KEY); SPUtils.remove(AUTHENTICATE_GATEWAYID_KEY); SPUtils.remove(AUTHENTICATE_IPADDRESS_KEY); @@ -70,7 +69,6 @@ localSecret = SPUtils.getString(AUTHENTICATE_LS_KEY, ""); gatewayId = SPUtils.getString(AUTHENTICATE_GATEWAYID_KEY, ""); ipAddress = SPUtils.getString(AUTHENTICATE_IPADDRESS_KEY, ""); isLocalEncrypt = SPUtils.getBoolean(AUTHENTICATE_IS_LS_KEY, false); } /** @@ -120,21 +118,15 @@ public String getGatewayId() { return gatewayId; } public void setGatewayId(String gatewayId) { this.gatewayId=gatewayId; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress){ this.ipAddress = ipAddress; } public boolean isLocalEncrypt() { return isLocalEncrypt; } public void setLocalEncrypt(boolean localEncrypt) { isLocalEncrypt = localEncrypt; SPUtils.put(AUTHENTICATE_IS_LS_KEY, isLocalEncrypt); } public GatewaySearchBean getCurrentGateway() { @@ -163,8 +155,8 @@ return (!topicStr.contains(TopicConstant.GATEWAY_AUTH_BROADCAST) //网关广播入网指令 && !topicStr.contains(TopicConstant.DEIVCE_AUTH_REQUEST) //入网认证 && !topicStr.contains(TopicConstant.GATEWAY_SEARCH) //搜索网关主题 && !topicStr.equals(TopicConstant.BROADCAST) && isLocalEncrypt//启用加密标志 && !topicStr.contains(TopicConstant.BROADCAST) && !TextUtils.isEmpty(localSecret) //有密钥就是加密 ); } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
@@ -1,8 +1,13 @@ package com.hdl.sdk.connect.protocol; import android.annotation.TargetApi; import android.os.Build; import android.util.Log; import androidx.annotation.RequiresApi; import com.google.gson.internal.bind.DateTypeAdapter; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.connect.config.HDLLinkConfig; import com.hdl.sdk.common.event.EventDispatcher; @@ -13,6 +18,7 @@ import com.hdl.sdk.socket.codec.ByteToMessageDecoder; import java.util.ArrayList; import java.util.Base64; import java.util.List; /** @@ -111,8 +117,9 @@ } } @Override protected synchronized LinkResponse decoder(Object msg) throws Exception { protected synchronized LinkResponse decoder(Object msg,String ipaddress) throws Exception { if (msg instanceof byte[]) { bytes.addAll(ByteUtils.toByteList((byte[]) msg)); //如果多条命令打包在一条数据中,都需要处理完 @@ -150,23 +157,36 @@ bytes.add(recevieBytes[i]); } LinkResponse response = new LinkResponse(); response.setSource_ipAddress(ipaddress); response.setTopic(topic); if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) { //需要解密 byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret()); // byte[] bodyBytes = AESUtils.decryptAES(body,AuthenticateConfig.getInstance().getLocalSecret()); if (bodyBytes != null) { response.setData(new String(bodyBytes, "utf-8")); // LogUtils.i("TAG", "解密 主题:"+response.getTopic()+ " body: "+response.getData()); body = bodyBytes; } else { //解密失败,返回原数据 response.setData(new String(body, "utf-8")); try { //之前的版本这块是明文的 if (!topic.contains("heartbeat_reply")) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) LogUtils.e("解密失败,数据内容是:\r\n" + Base64.getEncoder().encodeToString(body)); else { LogUtils.e("解密失败,数据内容是:\r\n" + new String(body, "utf-8")); } } } catch (Exception e) { } } } else { response.setData(new String(body, "utf-8")); } LogUtils.i( "LinkMessageDecoder->decoder:" + response.getTopic() + "\r\n" + response.getData()); String bodyString = new String(body, "utf-8"); response.setData(bodyString); LogUtils.i( "接收到数据:" + response.getTopic() + "\r\n" + response.getData()); //非正常数据,返回 if (!((bodyString.startsWith("{") &&bodyString.endsWith("}")) || (bodyString.startsWith("[")&&bodyString.endsWith("]")))) { continue; } //解析完成,topic发送一次 EventDispatcher.getInstance().post(response.getTopic(), response); } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -117,7 +117,7 @@ udpSocketBoot.bind(); } } catch (Exception e) { return null; // return null; } return udpSocketBoot; @@ -141,15 +141,15 @@ public void onMessage(Object msg) { NetworkAccessBroadcastResponse bean = getNetworkAccessBroadcastResponse(msg); if (bean != null) { LogUtils.i(TAG, "网关入网广播IP: " + bean.getIPAddress()); //移除监听 EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); LogUtils.i("网关入网广播IP: " + bean.getIPAddress()); String ipStr = bean.getIPAddress(); if (!TextUtils.isEmpty(ipStr)) { sendAuthenticateRequest(ipStr, request, callBack); } } //移除监听 EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); LogUtils.i(TAG, "移除监听 authEvent"); } }); } @@ -228,6 +228,7 @@ } }); } // /** // * 发送入网及认证请求 @@ -407,11 +408,11 @@ */ public void udpSendMsg(String topic, String bodyStr,boolean broadcast) { if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) { LogUtils.e("udpSendMsg", "参数不能为空"); LogUtils.e( "参数不能为空,不能发送UDP数据"); return; } if (!HDLLinkConfig.getInstance().checkIfCertified()) { LogUtils.e("udpSendMsg", "未认证,请先认证"); LogUtils.e("未认证,请先认证再调用UDP发送方法"); return; } LinkRequest message = new LinkRequest(topic, bodyStr); @@ -491,12 +492,12 @@ }.getType()); GatewaySearchBean searchBean = response.getObjects(); if (searchBean != null && !TextUtils.isEmpty(searchBean.getGatewayId())) { if (searchBean.getGatewayId().contains(searchGatewayId)) { searchBean.setIp_address(linkResponse.getSource_ipAddress()); if (searchBean.getGatewayId().contains(searchGatewayId)&&!TextUtils.isEmpty(searchGatewayId)) { removeSearchGatewayEvent();//移除搜索网关监听 isSearchGatewaySuccess.set(true);//搜索成功标记 searchGatewayCount.set(11);//次数标记 HDLLinkConfig.getInstance().setCurrentGateway(searchBean);//设置当前网关 HDLLinkConfig.getInstance().setLocalEncrypt(searchBean.isLocalEncrypt());//设置是否加密 if (mSearchGatewayCallBack != null) { mSearchGatewayCallBack.onSuccess(searchBean); } @@ -526,11 +527,14 @@ }.getType()); GatewaySearchBean gateway = response.getObjects(); if (gateway != null && !TextUtils.isEmpty(gateway.getGatewayId())) { //可能网关带过来的ip不对 gateway.setIp_address(linkResponse.getSource_ipAddress()); //主网关并且是当前绑定的网关 if ("true".equals(gateway.getMaster().toLowerCase()) && gateway.getGatewayId().equals(HDLLinkConfig.getInstance().getGatewayId())) { HDLLinkConfig.getInstance().setCurrentGateway(gateway);//设置当前网关 HDLLinkConfig.getInstance().setLocalEncrypt(gateway.isLocalEncrypt());//设置是否加密 HDLLinkConfig.getInstance().setIpAddress(gateway.getIp_address()); if(!TextUtils.isEmpty( gateway.getIp_address())) { HDLLinkConfig.getInstance().setIpAddress(gateway.getIp_address()); } //更新当前网关的信息 HDLLinkConfig.getInstance().reSaveConfig(); } @@ -583,9 +587,11 @@ } if (!isSearchGatewaySuccess.get()) { //搜索10次,指定网关都没回复,回调超时 callBackSearchGatewayTimeout(); LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时"); try { LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时"); //搜索10次,指定网关都没回复,回调超时 callBackSearchGatewayTimeout(); }catch (Exception e){} } } }).start(); HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -27,6 +27,7 @@ import com.hdl.sdk.connect.protocol.LinkMessageEncoder; import com.hdl.sdk.socket.SocketBoot; import com.hdl.sdk.socket.SocketOptions; import com.hdl.sdk.socket.client.IHeartbeat; import com.hdl.sdk.socket.client.TcpClient; import com.hdl.sdk.socket.codec.MessagePipeLine; import com.hdl.sdk.socket.listener.ConnectStatusListener; @@ -413,6 +414,27 @@ //如果没有初始化,或者网关IP更改了,就重新初始化 if (tcpBoot == null||!getTcpOptions().getIp().equals(getTcpIp())) { tcpBoot = TcpClient.init(getTcpIp(), getTcpPort(), getTcpOptions()); tcpBoot.SetHeartbeat(new IHeartbeat() { @Override public void heartbeat() { if(HDLLinkConfig.getInstance().getDeviceInfoBean()==null||HDLLinkConfig.getInstance().getDeviceInfoBean().getOID()==null) { LogUtils.i("DeviceInfoBean为空,需要设置才能正常心跳"); return; } String time = String.valueOf(System.currentTimeMillis()); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("id", IdUtils.getUUId()); jsonObject.addProperty("time_stamp", time); String topic = String.format(TopicConstant.HEARTBEAT, HDLLinkConfig.getInstance().getDeviceInfoBean().getOID()); LinkRequest message = new LinkRequest(topic, jsonObject.toString()); sendMsg(message.getSendBytes(), null, null, null); } }); } return tcpBoot; @@ -574,46 +596,48 @@ public void sendMsg(byte[] data, String eventTag, HDLLinkCallBack callBack, SendListener sendListener) { try { final AtomicInteger sendCount = new AtomicInteger(0); if(eventTag!=null) { final AtomicInteger sendCount = new AtomicInteger(0); final ScheduledExecutorService threadPool = ThreadToolUtils.getInstance().newScheduledThreadPool(1); final EventListener eventListener = new EventListener() { @Override public void onMessage(Object msg) { if (msg instanceof LinkResponse) { LogUtils.i("sendMsg onSuccess"); threadPool.shutdownNow(); LogUtils.i("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, this); if (callBack != null) { callBack.onSuccess(msg.toString()); final ScheduledExecutorService threadPool = ThreadToolUtils.getInstance().newScheduledThreadPool(1); final EventListener eventListener = new EventListener() { @Override public void onMessage(Object msg) { if (msg instanceof LinkResponse) { LogUtils.i("sendMsg onSuccess"); threadPool.shutdownNow(); LogUtils.i("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, this); if (callBack != null) { callBack.onSuccess(msg.toString()); } } } } }; }; threadPool.scheduleWithFixedDelay(new Runnable() { @Override public void run() { if (sendCount.get() < 3) { sendCount.set(sendCount.get() + 1); getTcp().sendMsg(data); } else { threadPool.shutdownNow(); LogUtils.e("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, eventListener); ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR)); threadPool.scheduleWithFixedDelay(new Runnable() { @Override public void run() { if (sendCount.get() < 3) { sendCount.set(sendCount.get() + 1); getTcp().sendMsg(data); } else { threadPool.shutdownNow(); LogUtils.e("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, eventListener); ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEND_ERROR)); } } } }); }); } } } }, 1000, 500, TimeUnit.MILLISECONDS); EventDispatcher.getInstance().register(eventTag, eventListener); }, 1000, 500, TimeUnit.MILLISECONDS); EventDispatcher.getInstance().register(eventTag, eventListener); } //先发送一次 getTcp().sendMsg(data, new SendListener() { @Override HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -21,7 +21,7 @@ */ public class HdlSocketHelper { private static final Long DEF_SEND_TIMEOUT = 500L; private static final Long DEF_SEND_TIMEOUT = 1000L; private static final int DEF_MAX_RETRY = 4; private static final int DEF_SEND_ONE = 1; HDLSDK/hdl-socket/build.gradle
@@ -9,7 +9,7 @@ minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion versionCode 2 versionName "1.0.3" versionName "1.0.10" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java
@@ -5,13 +5,18 @@ import androidx.collection.ArrayMap; import com.google.gson.JsonObject; import com.hdl.sdk.common.config.TopicConstant; import com.hdl.sdk.common.utils.IdUtils; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.ThreadToolUtils; import com.hdl.sdk.socket.annotation.ConnectStatus; import com.hdl.sdk.socket.client.IClient; import com.hdl.sdk.socket.client.IHeartbeat; import com.hdl.sdk.socket.listener.SendListener; import java.net.ConnectException; import java.util.Date; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingDeque; @@ -29,8 +34,17 @@ private ExecutorService connectThread; private ExecutorService sendThread; private ExecutorService receiveThread; private ExecutorService heartbeatThread; private final IClient client; private IHeartbeat iHeartbeat; public void SetHeartbeat(IHeartbeat iHeartbeat){ this.iHeartbeat=iHeartbeat; } /** * 当前接收到数据的时间 */ private static long time=System.currentTimeMillis(); /** * tcp是否已经连接 @@ -50,6 +64,7 @@ initConnectThread(); initReceiveThread(); initSendThread(); initHeartbeat(); } /** @@ -64,7 +79,7 @@ connected=true; client.onConnectStatus(ConnectStatus.CONNECTED); }catch(Exception e) { LogUtils.e(e.getMessage()); LogUtils.e("连接异常"+e.getMessage()); } } @@ -125,6 +140,7 @@ if (connected) { //读取数据 client.onHandleResponse(); time= System.currentTimeMillis(); } else { try { Thread.sleep(1000); @@ -157,7 +173,7 @@ if (!connected) { reconect(); } Thread.sleep(10*1000); Thread.sleep(3*1000); } catch (Exception e) { } @@ -166,6 +182,39 @@ }); } } /** * 初始化重新心跳线程 */ private void initHeartbeat() { if (heartbeatThread == null) { heartbeatThread = ThreadToolUtils.getInstance().newFixedThreadPool(1); heartbeatThread.execute(new Runnable() { @Override public void run() { while (true) { try { //10秒 if (connected && 10 * 1000 < (System.currentTimeMillis() - time)) { time = System.currentTimeMillis(); //心跳检测 try { if (iHeartbeat != null) iHeartbeat.heartbeat(); } catch (Exception e) { } } Thread.sleep(1000); } catch (Exception e) { } } } }); } } /** * 重新连接 */ HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IHeartbeat.java
New file @@ -0,0 +1,8 @@ package com.hdl.sdk.socket.client; /** * Created by hxb on 2022/2/16. */ public interface IHeartbeat { void heartbeat(); } HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java
@@ -3,6 +3,7 @@ import com.hdl.sdk.common.utils.ByteUtils; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.ThreadToolUtils; import com.hdl.sdk.socket.SocketBoot; import com.hdl.sdk.socket.SocketOptions; @@ -15,6 +16,8 @@ import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.StandardSocketOptions; import java.util.ArrayList; import java.util.List; @@ -67,12 +70,14 @@ @Override public void connect() throws Exception { mSocket = getSocket(); SocketOptions options = getOptions(); mSocket.connect(new InetSocketAddress(ip, port)); // SocketOptions options = getOptions(); mSocket.connect(new InetSocketAddress(ip, port), 3 * 1000); mSocket.setTcpNoDelay(true); mSocket.setReuseAddress(true); mSocket.setKeepAlive(true); // mSocket.setKeepAlive(true); mSocket.setSoTimeout(25 * 1000); tcpClientList.add(this); } @@ -103,14 +108,18 @@ public void onHandleResponse() throws Exception { final InputStream stream = getInputStream(); if (stream != null && getOptions() != null) { int len=0; while ( (len=getInputStream().read(readBuffer)) != -1) { while ( true) { int len=getInputStream().read(readBuffer); if(len<=0){ throw new Exception("接收异常,接收数据长度len="+len); } IHandleMessage handleMessage = getOptions().getHandleMessage(); if (handleMessage != null) { byte []bytes = new byte[len]; System.arraycopy(readBuffer,0,bytes,0,len); //完整的数据才回调 handleMessage.read(bytes); handleMessage.read(bytes,ip); } } } @@ -120,14 +129,10 @@ public void sendMsg(byte[] msg) throws Exception { final OutputStream outputStream = getOutStream(); if (outputStream != null && getOptions() != null) { try { IHandleMessage handleMessage = getOptions().getHandleMessage(); handleMessage.write(handleMessage.write(msg)); getOutStream().write(msg); } finally { outputStream.write(msg); outputStream.flush(); } } } HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java
@@ -154,7 +154,7 @@ if (handleMessage != null) { byte[] data = new byte[receivePacket.getLength()]; System.arraycopy(receivePacket.getData(), 0, data, 0, data.length); handleMessage.read(data); handleMessage.read(data,receivePacket.getAddress().getHostAddress()); } } catch (Exception e) { HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/ByteToMessageDecoder.java
@@ -5,12 +5,12 @@ */ public abstract class ByteToMessageDecoder<T> implements IHandleFlow<T> { protected abstract T decoder(Object msg) protected abstract T decoder(Object msg,String ipaddress) throws Exception; @Override public final T read(Object data) throws Exception { return decoder(data); public final T read(Object data,String ipaddress) throws Exception { return decoder(data,ipaddress); } @Override HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleFlow.java
@@ -5,7 +5,7 @@ */ public interface IHandleFlow<T> { T read(Object data) throws Exception; T read(Object data,String ipaddress) throws Exception; byte[] write(byte[] data) throws Exception; HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleMessage.java
@@ -4,7 +4,7 @@ * Created by Tong on 2021/9/27. */ public interface IHandleMessage { void read(byte[] data) throws Exception; void read(byte[] data,String ipaddress) throws Exception; byte[] write(byte[] data) throws Exception; } HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessagePipeLine.java
@@ -22,11 +22,11 @@ } @Override public void read(byte[] data) throws Exception { public void read(byte[] data,String ipaddress) throws Exception { Object out = data; for (int i = 0; i < queue.size(); i++) { IHandleFlow flow = queue.get(i); Object read = flow.read(out); Object read = flow.read(out,ipaddress); try { out = Objects.requireNonNull(read); } catch (Exception ignored) { HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessageToByteEncoder.java
@@ -11,7 +11,7 @@ throws Exception; @Override public final Object read(Object data) { public final Object read(Object data,String ipaddress) { return data; } HDLSDK_DEMO.zipBinary files differ
HDLSDK_DEMO/app/libs/hdl-common-V1.0.3.aarBinary files differ
HDLSDK_DEMO/app/libs/hdl-common-V1.0.8.aarBinary files differ
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.3.aarBinary files differ
HDLSDK_DEMO/app/libs/hdl-connect-V1.0.8.aarBinary files differ
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.3.aarBinary files differ
HDLSDK_DEMO/app/libs/hdl-socket-V1.0.8.aarBinary files differ
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -72,6 +72,75 @@ removeAllTopicsListener(); } void initDeviceInfo() { AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean(); infoBean.setDeviceMAC("AA000000000000AF"); infoBean.setIPMAC("AA000000000000AF"); infoBean.setDeviceName("音乐播放器");//设备名字 infoBean.setDeviceModel("MCLog.431");//设备型号 infoBean.setAccessMode("WIFI"); infoBean.setIPGateway("192.168.1.1"); infoBean.setIPAddress("192.168.1.102"); infoBean.setGateway_type("music.standard"); infoBean.setHw_version("HW2.0"); infoBean.setFw_version("Fw1.0"); infoBean.setOID("010105000000FE10");//每个设备oid都要不一样 infoBean.setSid("110105000000FE08110100000000");//每个设备的sid都要不一样 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 = "AA000000000000AC";//设备唯一MAC地址 String secret = "ee62124c151b737c";//通过spk和mac提交云端认证后分配的secret String mac_key = stringToMD5(stringToMD5(macStr + secret)); String versionString = "HDL_V1.0.1";// String time = String.valueOf(System.currentTimeMillis()); HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr); //1.设置认证信息 AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean(); requestBean.setMAC(macStr); requestBean.setSupplier("WISE"); 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()); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -82,7 +151,7 @@ rv.setLayoutManager(new LinearLayoutManager(this)); checkIfCertified(); initDeviceInfo();//初始化 registerAllTopicsListener(); ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { @@ -250,69 +319,7 @@ HDLLink.getInstance().removeAllTopicsListener(allTopicsListener); } /** * 入网认证 */ void sendAuthenticateRequest() { tv.setText("开始入网认证..."); //认证提交参数准备 //测试服务 String spkStr = "ir.module";//产品spk String macStr = "AA000000000000BB";//设备唯一MAC地址 String secret = "87ae414b7a853f65";//通过spk和mac提交云端认证后分配的secret //正式服务器 // String spkStr = "screen.mirror";//产品spk // String macStr = "AA000000000000AC";//设备唯一MAC地址 // String secret = "ee62124c151b737c";//通过spk和mac提交云端认证后分配的secret String mac_key = stringToMD5(stringToMD5(macStr + secret)); String versionString = "HDL_V1.0.1";// String time = String.valueOf(System.currentTimeMillis()); //1.设置认证信息 AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean(); requestBean.setMAC(macStr); requestBean.setSupplier("raysgem"); requestBean.setFirmwareVersion(versionString); requestBean.setHardwareModel("1956F"); AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean(); authbean.setSpk(spkStr); authbean.setMACKey(mac_key); authbean.setRequest(requestBean); //2.设置设备信息 AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean(); infoBean.setDeviceMAC(macStr); infoBean.setIPMAC(macStr); infoBean.setDeviceName("红外宝");//设备名字 infoBean.setDeviceModel("HDL");// infoBean.setAccessMode("WIFI"); infoBean.setIPGateway("192.168.88.1"); infoBean.setIPAddress(IpUtils.getIP(this)); infoBean.setOID("010105000000FE08"); infoBean.setSid("010105000000FE08110100000000"); // infoBean.set AuthenticateRequest.VersionBean[] versionBeans = new AuthenticateRequest.VersionBean[]{new AuthenticateRequest.VersionBean("FW", versionString), new AuthenticateRequest.VersionBean("HW", "1956F")}; infoBean.setVersions(versionBeans); AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, infoBean, authbean); HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() { @Override 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;