| | |
| | | package com.hdl.sdk.connect.socket; |
| | | |
| | | import static com.hdl.sdk.common.config.TopicConstant.DEIVCE_AUTH_REQUEST; |
| | | |
| | | import android.text.TextUtils; |
| | | import android.util.Log; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.google.gson.JsonArray; |
| | | import com.google.gson.JsonObject; |
| | | import com.google.gson.reflect.TypeToken; |
| | | import com.hdl.sdk.common.HDLSdk; |
| | | import com.hdl.sdk.common.config.TopicConstant; |
| | | 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.IdUtils; |
| | | import com.hdl.sdk.common.utils.IpUtils; |
| | | import com.hdl.sdk.common.utils.LogUtils; |
| | | import com.hdl.sdk.common.utils.ThreadToolUtils; |
| | | import com.hdl.sdk.connect.HDLLink; |
| | | import com.hdl.sdk.common.utils.gson.GsonConvert; |
| | | import com.hdl.sdk.connect.bean.LinkRequest; |
| | | import com.hdl.sdk.connect.bean.LinkResponse; |
| | | import com.hdl.sdk.connect.bean.request.AuthenticateRequest; |
| | | import com.hdl.sdk.connect.bean.request.DeviceControlRequest; |
| | | import com.hdl.sdk.connect.bean.request.GatewayInfoRequest; |
| | | import com.hdl.sdk.connect.bean.response.AuthenticateResponse; |
| | | import com.hdl.sdk.connect.bean.response.BaseLocalResponse; |
| | | import com.hdl.sdk.connect.bean.response.GatewaySearchBean; |
| | | 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.client.UdpClient; |
| | |
| | | import com.hdl.sdk.socket.udp.UdpSocketBoot; |
| | | import com.hdl.sdk.socket.udp.UdpSocketOptions; |
| | | |
| | | import java.net.InetSocketAddress; |
| | | import java.util.List; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import static com.hdl.sdk.common.config.TopicConstant.DEIVCE_AUTH_REQUEST; |
| | | |
| | | /** |
| | | * Created by jlchen on 11/11/21. |
| | |
| | | /** |
| | | * instance |
| | | */ |
| | | private volatile static HDLAuthSocket instance; |
| | | private static final HDLAuthSocket instance = new HDLAuthSocket(); |
| | | |
| | | private HDLAuthSocket() { |
| | | initListenerGatewayEvent(); |
| | |
| | | * |
| | | * @return HDLAuthSocket |
| | | */ |
| | | public static synchronized HDLAuthSocket getInstance() { |
| | | if (instance == null) { |
| | | synchronized (HDLLinkConfig.class) { |
| | | if (instance == null) { |
| | | instance = new HDLAuthSocket(); |
| | | } |
| | | } |
| | | } |
| | | public static HDLAuthSocket getInstance() { |
| | | // if (instance == null) { |
| | | // synchronized (HDLAuthSocket.class) { |
| | | // if (instance == null) { |
| | | // instance = new HDLAuthSocket(); |
| | | // } |
| | | // } |
| | | // } |
| | | return instance; |
| | | } |
| | | |
| | |
| | | * |
| | | * @return 返回当前对象 |
| | | */ |
| | | private UdpSocketBoot getUdpBoot() { |
| | | private synchronized UdpSocketBoot getUdpBoot() { |
| | | try { |
| | | if (udpSocketBoot == null) { |
| | | udpSocketBoot = UdpClient.init(UDP_PORT, getUdpOptions()); |
| | | udpSocketBoot.bind(); |
| | | |
| | | LogUtils.i("初始化Socket udp"); |
| | | } |
| | | } catch (Exception e) { |
| | | // return null; |
| | | LogUtils.e("初始化Socket udp异常" + e.getMessage()); |
| | | } |
| | | |
| | | return udpSocketBoot; |
| | | } |
| | | |
| | | public void init() { |
| | | getUdpBoot(); |
| | | } |
| | | |
| | | /** |
| | |
| | | //2.构建监听Listener |
| | | // authEvent = |
| | | //3.监听网关广播的入网指令 |
| | | EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); |
| | | 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); |
| | | 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()); |
| | | } |
| | | //移除监听 |
| | | EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); |
| | | LogUtils.i(TAG, "移除监听 authEvent"); |
| | | } |
| | | }); |
| | | } |
| | |
| | | public void endAuthenticateRequest() { |
| | | //移除监听 |
| | | EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); |
| | | } |
| | | |
| | | /** |
| | | * 上报从网关信息 |
| | | * |
| | | * @param callBack 回调 |
| | | */ |
| | | public void UploadGatewayInfo(HDLLinkCallBack callBack) { |
| | | String time = String.valueOf(System.currentTimeMillis()); |
| | | final BaseLocalResponse<GatewayInfoRequest> data = new BaseLocalResponse<>(); |
| | | data.setId(IdUtils.getUUId()); |
| | | data.setTime_stamp(time); |
| | | |
| | | 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()); |
| | | request.setGateway_type(authenticateDeviceInfoBean.getGateway_type()); |
| | | request.setAccess_mode(authenticateDeviceInfoBean.getAccessMode()); |
| | | request.setOid(authenticateDeviceInfoBean.getOID()); |
| | | request.setSid(authenticateDeviceInfoBean.getSid()); |
| | | request.setSupplier(authenticateDeviceInfoBean.getSupplier()); |
| | | |
| | | if (authenticateDeviceInfoBean.getSupplier() == null) { |
| | | AuthenticateRequest.RequestBean requestBean = HDLLinkConfig.getInstance().getRequestBean(); |
| | | if (requestBean != null) { |
| | | request.setSupplier(requestBean.getSupplier()); |
| | | } |
| | | } |
| | | |
| | | request.setHw_version(authenticateDeviceInfoBean.getHw_version()); |
| | | request.setFw_version(HDLSdk.getInstance().getVersion());//sdk版本 |
| | | request.setIp_address(authenticateDeviceInfoBean.getIPAddress()); |
| | | request.setMaster("false"); |
| | | request.setLocalEncrypt(false); |
| | | request.setHomeId(HDLLinkConfig.getInstance().getHomeId()); |
| | | |
| | | data.setObjects(request); |
| | | |
| | | String topic = HDLLinkConfig.getInstance().getFullTopic(TopicConstant.GATEWAY_SEARCH_REPLY); |
| | | LinkRequest message = new LinkRequest(topic, |
| | | GsonConvert.getGson().toJson(data)); |
| | | |
| | | String ip = IpUtils.getBroadcastAddress(); |
| | | HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, null); |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | try { |
| | | AuthenticateResponse bean = getAuthenticateResponseBean(msg); |
| | | if (bean != null) { |
| | | if (bean.getCode().equals("200")) { |
| | | if (bean.getCode().equals("200") || bean.getCode().equals("0")) { |
| | | 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()); |
| | | |
| | | //判断网关是否已经注册到云端 |
| | | if (TextUtils.isEmpty(localSecret) || TextUtils.isEmpty(gatewayId)) { |
| | | Log.d("panlili", "认证成功----->localSecret= " + localSecret); |
| | | 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); |
| | | HDLLinkConfig.getInstance().setRequestBean(request.getAuth().getRequest()); |
| | | callBack.onSuccess("认证成功"); |
| | | |
| | | // UploadDeviceAuth(request.getObjects().getDeviceMAC(), "0", "success", bean.getCode(), null); |
| | | } |
| | | } else if (bean.getCode().equals("14013")){ |
| | | } else if (bean.getCode().equals("14013")) { |
| | | //认证失败,该MAC对应的设备密钥不存在 |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_MAC_KEY_ERROR_)); |
| | | } else{ |
| | | |
| | | // UploadDeviceAuth(request.getObjects().getDeviceMAC(), "-1", "fail", bean.getCode(), null); |
| | | } else if (bean.getCode().equals("124013")) { |
| | | //认证失败,该MAC对应的设备密钥不存在 |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_124013_ERROR)); |
| | | |
| | | } else if (bean.getCode().equals("124015")) { |
| | | //认证失败,设备厂家不匹配 |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_124015_ERROR)); |
| | | |
| | | } else { |
| | | //认证失败,错误码: |
| | | LogUtils.e("认证失败,错误码:" + bean.getCode()); |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR)); |
| | | |
| | | // UploadDeviceAuth(request.getObjects().getDeviceMAC(), "-1", "fail", bean.getCode(), null); |
| | | } |
| | | } else { |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR)); |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | public void UploadDeviceAuth(String mac, String result, String message, String auth_code, HDLLinkCallBack callBack) { |
| | | HDLSocket.getInstance().UploadDeviceAuth(mac, result, message, auth_code, new HDLLinkCallBack() { |
| | | @Override |
| | | public void onSuccess(String msg) { |
| | | if (callBack != null) { |
| | | callBack.onSuccess(msg); |
| | | } |
| | | LogUtils.i(TAG, "onSuccess: " + msg); |
| | | } |
| | | |
| | | @Override |
| | | public void onError(HDLLinkException e) { |
| | | if (callBack != null) { |
| | | callBack.onError(e); |
| | | } |
| | | LogUtils.i(TAG, "onError: " + e.getMsg() + " " + e.getCode()); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | public void linkBroadcast(String oid, HDLLinkCallBack callBack) { |
| | | if (TextUtils.isEmpty(oid)) { |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); |
| | | } |
| | | |
| | | Gson gs = new Gson(); |
| | | JsonArray jsonArray = new JsonArray(); |
| | | JsonObject jsonObject = new JsonObject(); |
| | | jsonObject.addProperty("oid", oid); |
| | | jsonArray.add(jsonObject); |
| | | String requestStr = gs.toJson(jsonArray); |
| | | |
| | | String topic = String.format(TopicConstant.LINK_BROADCAST, HDLLinkConfig.getInstance().getDeviceInfoBean().getOID()); |
| | | LinkRequest message = new LinkRequest(topic, requestStr); |
| | | |
| | | String ip = IpUtils.getBroadcastAddress(); |
| | | |
| | | HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() { |
| | | @Override |
| | | public void onSucceed(Object msg) { |
| | | if (callBack == null) return; |
| | | try { |
| | | callBack.onSuccess("更新成功"); |
| | | LogUtils.i(TAG, "onSucceed: msg= " + msg); |
| | | } catch (Exception e) { |
| | | 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)); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | // /** |
| | | // * 发送入网及认证请求 |
| | |
| | | * 通用发送指令 |
| | | * 1秒没响应就让他重新发送,重试3次 |
| | | * |
| | | * @param topic 发送数据 |
| | | * @param bodyStr 回复的主题 |
| | | * @param topic 发送数据 |
| | | * @param bodyStr 回复的主题 |
| | | * @param broadcast 是否要广播 |
| | | * @param callBack 回调 |
| | | * @param callBack 回调 |
| | | */ |
| | | public void udpSendMsg(String topic, String bodyStr,boolean broadcast, HDLLinkResponseCallBack callBack) { |
| | | public void udpSendMsg(String topic, String bodyStr, boolean broadcast, HDLLinkResponseCallBack callBack) { |
| | | if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) { |
| | | if (callBack != null) { |
| | | callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); |
| | |
| | | |
| | | LinkRequest message = new LinkRequest(topic, bodyStr); |
| | | String ip = HDLLinkConfig.getInstance().getIpAddress(); |
| | | if(broadcast) { |
| | | if (broadcast) { |
| | | ip = IpUtils.getBroadcastAddress(); |
| | | } |
| | | HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() { |
| | |
| | | /** |
| | | * 通用发送指令 只发一次,不监听回复,不重发 |
| | | * |
| | | * @param topic 发送数据 |
| | | * @param bodyStr 回复的主题 |
| | | * @param topic 发送数据 |
| | | * @param bodyStr 回复的主题 |
| | | * @param broadcast 是否广播 |
| | | */ |
| | | public void udpSendMsg(String topic, String bodyStr,boolean broadcast) { |
| | | 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); |
| | | String ip = HDLLinkConfig.getInstance().getIpAddress(); |
| | | if(broadcast) { |
| | | if (broadcast) { |
| | | ip = IpUtils.getBroadcastAddress(); |
| | | } |
| | | HdlSocketHelper.sendUdpOne(getUdpBoot(), ip, UDP_PORT, message); |
| | |
| | | final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() { |
| | | }.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); |
| | | } |
| | |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | |
| | | LogUtils.i("panlili:" + e.toString()); |
| | | } |
| | | } |
| | | }; |
| | |
| | | }.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()); |
| | | LogUtils.i("接收到网关信息:" + HDLLinkConfig.getInstance().getIpAddress()); |
| | | } |
| | | //更新当前网关的信息 |
| | | HDLLinkConfig.getInstance().reSaveConfig(); |
| | | } |
| | |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | |
| | | LogUtils.i("panlili:" + e.toString()); |
| | | } |
| | | } |
| | | }; |
| | |
| | | } |
| | | |
| | | if (!isSearchGatewaySuccess.get()) { |
| | | //搜索10次,指定网关都没回复,回调超时 |
| | | callBackSearchGatewayTimeout(); |
| | | LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时"); |
| | | try { |
| | | LogUtils.e("搜索网关", "搜索10次,指定网关都没回复,回调超时"); |
| | | //搜索10次,指定网关都没回复,回调超时 |
| | | callBackSearchGatewayTimeout(); |
| | | } catch (Exception e) { |
| | | } |
| | | } |
| | | } |
| | | }).start(); |