package com.hdl.sdk.connect.socket; import android.text.TextUtils; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.hdl.sdk.common.event.EventDispatcher; import com.hdl.sdk.common.event.EventListener; import com.hdl.sdk.common.exception.HDLLinkCode; import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.connect.bean.response.AuthenticateResponse; import com.hdl.sdk.connect.bean.response.NetworkAccessBroadcastResponse; import com.hdl.sdk.connect.callback.BaseCallBack; import com.hdl.sdk.connect.callback.HDLLinkCallBack; import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack; import com.hdl.sdk.connect.config.HDLLinkConfig; import com.hdl.sdk.common.config.TopicConstant; import com.hdl.sdk.common.utils.IdUtils; import com.hdl.sdk.common.utils.IpUtils; import com.hdl.sdk.common.utils.gson.GsonConvert; import com.hdl.sdk.connect.bean.request.AuthenticateRequest; import com.hdl.sdk.connect.bean.response.BaseLocalResponse; import com.hdl.sdk.connect.bean.request.DeviceControlRequest; import com.hdl.sdk.connect.bean.response.GatewaySearchBean; import com.hdl.sdk.connect.bean.LinkRequest; import com.hdl.sdk.connect.bean.LinkResponse; import com.hdl.sdk.connect.protocol.LinkMessageDecoder; import com.hdl.sdk.connect.protocol.LinkMessageEncoder; import com.hdl.sdk.socket.SocketBoot; import com.hdl.sdk.socket.SocketOptions; import com.hdl.sdk.socket.client.UdpClient; import com.hdl.sdk.socket.codec.MessagePipeLine; import com.hdl.sdk.socket.listener.SendListener; import java.io.UnsupportedEncodingException; import java.util.List; import static com.hdl.sdk.common.config.TopicConstant.DEIVCE_AUTH_REQUEST; /** * Created by jlchen on 11/11/21. * * @Description : HDLAuthSocket */ public class HDLAuthSocket { private static final String TAG = "HDLAuth"; /** * udp默认端口 */ private static final int UDP_PORT = 8585; private static SocketBoot updBoot; // private EventListener authEvent; /** * udp默认组播ip */ private static final String UDP_GROUP_IP = "239.0.168.188"; /** * instance */ private volatile static HDLAuthSocket instance; // public interface CallBack extends BaseCallBack { // void onSuccess(String msg); // } /** * getInstance * * @return HDLAuthSocket */ public static synchronized HDLAuthSocket getInstance() { if (instance == null) { synchronized (HDLLinkConfig.class) { if (instance == null) { instance = new HDLAuthSocket(); } } } return instance; } private SocketOptions getUdpOptions() { final SocketOptions options = new SocketOptions(); final MessagePipeLine pipeLine = new MessagePipeLine(); pipeLine.add(new LinkMessageDecoder()); pipeLine.add(new LinkMessageEncoder()); options.setHandleMessage(pipeLine); options.setEnabledHeartbeat(false); return options; } private SocketBoot getUdpBoot(String ip) { if (updBoot == null) { updBoot = UdpClient.init(ip, UDP_PORT, getUdpOptions()); updBoot.connect(); } return updBoot; } /** * 开始监听和发起入网及认证请求 * * @param request 认证请求信息 * @param callBack 结果回调 */ public void startAuthenticateRequest(AuthenticateRequest request, HDLLinkCallBack callBack) { HDLLinkConfig.getInstance().clearConfig(); //1.启动Socket 开启监听 getUdpBoot(IpUtils.getBroadcastAddress()); //2.构建监听Listener // authEvent = //3.监听网关广播的入网指令 EventDispatcher.getInstance().register(TopicConstant.GATEWAY_AUTH_BROADCAST, new EventListener() { @Override public void onMessage(Object msg) { NetworkAccessBroadcastResponse bean = getNetworkAccessBroadcastResponse(msg); if(bean != null){ LogUtils.i(TAG, "网关入网广播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"); } }); } /** * 结束监听入网及认证广播 */ public void endAuthenticateRequest(){ //移除监听 EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); } /** * 发送入网及认证请求 * * @param ip 网关IP * @param request 认证请求信息 * @param callBack 结果回调 */ public void sendAuthenticateRequest(String ip, AuthenticateRequest request, HDLLinkCallBack callBack) { if (request == null) { callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); } String topic = DEIVCE_AUTH_REQUEST; Gson gs = new Gson(); String requestStr = gs.toJson(request); LinkRequest message = new LinkRequest(topic, requestStr); HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; AuthenticateResponse bean = getAuthenticateResponseBean(msg); if(bean != null){ String localSecret = bean.getAuth().getLocalSecret(); String gatewayId = bean.getObjects().getGatewayID(); String ipAddress = bean.getObjects().getIPAddress(); //判断网关是否已经注册到云端 if(TextUtils.isEmpty(localSecret) ||TextUtils.isEmpty(gatewayId)){ //认证失败,网关未注册到云端 callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED)); }else{ HDLLinkConfig.getInstance().saveConfig(localSecret,gatewayId,ipAddress); callBack.onSuccess("认证成功"); } }else{ callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR)); } } @Override public void onFailure() { LogUtils.i(TAG, "onFailure: "); if(callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } }); } // /** // * 发送入网及认证请求 // * // * @param callBack 结果回调 // */ // public void sendAuthenticateRequest(CallBack callBack) { // String macStr = "AA000000000000BB"; // String secret = "87ae414b7a853f65"; // 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("HDL"); // requestBean.setFirmwareVersion(versionString); // requestBean.setHardwareModel("1956F"); // AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean(); // authbean.setSpk("ir.module"); // authbean.setMACKey(mac_key); // authbean.setRequest(requestBean); // // // //2.设置设备信息 // AuthenticateDeviceInfoBean infoBean = new AuthenticateDeviceInfoBean(); // infoBean.setDeviceMAC(macStr); // infoBean.setIPMAC(macStr); // infoBean.setDeviceName("HDL面板"); // infoBean.setAccessMode("HDL"); // infoBean.setOID(getOid()); // infoBean.setSid(getSid()); //// 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); // // String ip = IpUtils.getBroadcastAddress(); // ip = "192.168.10.102"; // sendAuthenticateRequest(ip, request, callBack); // } public interface SearchGatewayCallBack extends BaseCallBack{ /** * 搜索网关成功 * * @param gatewaySearchBean */ void onSuccess(GatewaySearchBean gatewaySearchBean); } /** * 开始搜索所有网关,有网关回复就回调,上层自己做去重判断 * * @param callBack 回调 */ public void startSearchAllGateway(SearchGatewayCallBack callBack) { } /** * 暂停搜索网关 */ public void endSearchAllGateway() { } /** * 组播搜索指定网关是否在线,搜索到则返回指定的网关对象 * @param callBack 回调 */ public void searchGatewayMulticast(SearchGatewayCallBack callBack) { searchGateway(HDLLinkConfig.getInstance().getGatewayId(), UDP_GROUP_IP, callBack); } /** * 组播搜索指定网关是否在线,搜索到则返回指定的网关对象 * @param callBack 回调 */ public void searchGatewayBroadcast(SearchGatewayCallBack callBack) { String ip = IpUtils.getBroadcastAddress(); searchGateway(HDLLinkConfig.getInstance().getGatewayId(), ip, callBack); } /** * 搜索指定网关是否在线,搜索到则返回指定的网关对象 * * @param gatewayId 网关id * @param ip 接收目标的ip地址 * @param callBack 回调 */ public void searchGateway(String gatewayId, String ip, SearchGatewayCallBack callBack) { String time = String.valueOf(System.currentTimeMillis()); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("id", IdUtils.getUUId()); jsonObject.addProperty("time_stamp", time); LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH, jsonObject.toString()); HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { GatewaySearchBean searchBean = getGatewaySearchBean(msg); if (searchBean != null && searchBean.getGatewayId().contains(gatewayId)) { LogUtils.i(TAG, "onSuccess: "); HDLLinkConfig.getInstance().setCurrentGateway(searchBean); HDLLinkConfig.getInstance().setLocalEncrypt(searchBean.isLocalEncrypt()); callBack.onSuccess(searchBean); }else { } } @Override public void onFailure() { LogUtils.i(TAG, "onFailure: "); callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } }); } /** * 设备控制 */ public void propertyDown(List request, HDLLinkCallBack callBack) { String time = String.valueOf(System.currentTimeMillis()); final BaseLocalResponse> data = new BaseLocalResponse<>(); data.setId(IdUtils.getUUId()); data.setTime_stamp(time); data.setObjects(request); String topic = HDLLinkConfig.getInstance().getFullTopic(TopicConstant.PROPERTY_DOWN); LinkRequest message = new LinkRequest(topic, GsonConvert.getGson().toJson(data)); String ip = IpUtils.getBroadcastAddress(); HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; callBack.onSuccess("控制成功"); } @Override public void onFailure() { if(callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_CONTROL_FAILURE_ERROR)); } }); } /** * 通用发送指令 * 1秒没响应就让他重新发送,重试3次 * @param topic 发送数据 * @param bodyStr 回复的主题 * @param callBack 回调 */ public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) { if(TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) { if(callBack != null){ callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); } return; } LinkRequest message = new LinkRequest(topic, bodyStr); String ip = IpUtils.getBroadcastAddress(); HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; callBack.onSuccess((LinkResponse) msg); } @Override public void onFailure() { if(callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } } ); } private GatewaySearchBean getGatewaySearchBean(Object msg) { GatewaySearchBean searchBean = null; if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; String data = linkResponse.getData(); if (!TextUtils.isEmpty(data)) { final BaseLocalResponse response = GsonConvert.getGson().fromJson(data, new TypeToken>() { }.getType()); searchBean = response.getObjects(); } } return searchBean; } private AuthenticateResponse getAuthenticateResponseBean(Object msg) { AuthenticateResponse mBean = null; if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; String data = linkResponse.getData(); if (!TextUtils.isEmpty(data)) { AuthenticateResponse response = GsonConvert.getGson().fromJson(data, new TypeToken() { }.getType()); mBean = response; } } return mBean; } private NetworkAccessBroadcastResponse getNetworkAccessBroadcastResponse(Object msg){ NetworkAccessBroadcastResponse mBean = null; if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; String data = linkResponse.getData(); if (!TextUtils.isEmpty(data)) { NetworkAccessBroadcastResponse response = GsonConvert.getGson().fromJson(data, new TypeToken() { }.getType()); mBean = response; } } return mBean; } }