package com.basic.security.utils; import android.os.SystemClock; import android.text.TextUtils; import com.basic.security.base.BaseApplication; import com.basic.security.manager.PersonManager; import com.basic.security.manager.RemoteInDoorManager; import com.basic.security.manager.RemoteOutdoorManager; import com.basic.security.model.ModelAdapter; import com.basic.security.model.Person; import com.basic.security.model.PersonSocket; import com.basic.security.utils.socket.BitmapListener; import com.basic.security.utils.socket.YuvToJpgFrameBufferManager; import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import org.apache.commons.io.IOUtils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SocketUtil { public ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); public Socket socket = null; public byte[] buffer = new byte[1]; public DataInputStream dataInputStream; public DataOutputStream dataOutStream; public ObjectOutputStream objectOutputStream; public ObjectInputStream objectInputStream; public YuvToJpgFrameBufferManager mBufferManager; public byte[] imageBuff; public String remoteIp = ""; public BitmapListener cameraDataListener; public SocketUtil() { } public static List getRpcCallIp() { List ipList = new ArrayList<>(); if (Constants.isIndoor) { ipList = RemoteOutdoorManager.getOutdoorDeviceIp(); } if (Constants.isOutdoor) { ipList = RemoteInDoorManager.getIndoorDeviceIp(); } List finalList = new ArrayList<>(); for (String ip : ipList) { if (!TextUtils.isEmpty(ip)) { finalList.add(ip); } } // LogUtil.println("getRpcCallIp " + finalList); return finalList; } public static void rpcCallAsyncCommonSave(ModelAdapter modelAdapter) { rpcCallAsync(modelAdapter, PersonSocket.requestTypeAsyncSave); } public static void rpcCallAsyncCommonDelete(ModelAdapter modelAdapter) { rpcCallAsync(modelAdapter, PersonSocket.requestTypeAsyncDelete); } public static void rpcCallAsyncCommonSignal(String signalValue) { ModelAdapter modelAdapter = new ModelAdapter(); modelAdapter.setString(PersonSocket.signalValue, signalValue); rpcCallAsync(modelAdapter, PersonSocket.signal); } public static void rpcCallAsync(ModelAdapter modelAdapter, String requestType) { if (!Constants.isUseSocketRpc) { return; } BaseApplication.getApplication().executorService.execute(() -> { List remoteIpList = getRpcCallIp(); for (String remoteIp : remoteIpList) { try { SocketUtil socketUtil = new SocketUtil(); try { byte[] modelMapByteArray = new byte[]{}; modelMapByteArray = ObjectUtil.toByteArray(modelAdapter.model); Map requestMap = new HashMap<>(); requestMap.put(PersonSocket.modelMapByteArrayLength, modelMapByteArray.length + ""); requestMap.put(PersonSocket.requestType, requestType); socketUtil.openSocket(remoteIp, Constants.personServerPort); socketUtil.writeMap(requestMap); if (modelMapByteArray.length > 0) { socketUtil.writeByteArray(modelMapByteArray); } Map responseMap = socketUtil.readJsonAsMap(); // System1.out.println("SocketUtil.rpcCallAsync " + responseMap + " " + requestType + " remoteIp=" + remoteIp + " " + Constants.personServerPort); } catch (Exception e) { e.printStackTrace(); } finally { socketUtil.close(); } } catch (Exception e) { e.printStackTrace(); } } }); } public static void rpcCallSaveHintSignUp(ModelAdapter hintSignUpMassage) { rpcCallAsyncCommonSave(hintSignUpMassage); } public static void rpcCallSaveHintDoorAccess(ModelAdapter hintDoorAccess) { rpcCallAsyncCommonSave(hintDoorAccess); } public static void rpcCallSaveHintRecognize(ModelAdapter hintRecognize) { rpcCallAsyncCommonSave(hintRecognize); } public static void rpcCallSaveTimeRule(ModelAdapter timeRule) { rpcCallAsyncCommonSave(timeRule); } public static void rpcCallSaveVisit(ModelAdapter visit) { rpcCallAsyncCommonSave(visit); } public static void rpcCallInitTreeNodeList() { rpcCallAsyncCommonSignal(PersonSocket.signalInitTreeNodeList); } public static void rpcCallDeleteOrg(ModelAdapter org) { rpcCallAsyncCommonDelete(org); } public static void rpcCallSaveOrg(ModelAdapter org) { rpcCallAsyncCommonSave(org); } public static void rpcCallSendIdCard(IdCard idcard) { ModelAdapter modelAdapter = new ModelAdapter(); modelAdapter.model = idcard.toMap(); rpcCallAsyncCommonSave(modelAdapter); } public static void rpcCallSavePersonIdentity(ModelAdapter personIdentity) { rpcCallAsyncCommonSave(personIdentity); } public static void rpcCallSavePerson(ModelAdapter person) { byte[] personArray = new byte[]{}; byte[] camera_image_path = person.getBlob(Person.camera_image_path); if (camera_image_path != null && camera_image_path.length > 0) { person.model.put(PersonSocket.camera_image_path_byte_array, camera_image_path); } rpcCallAsyncCommonSave(person); } public static void rpcCallDeletePersonIdentity(ModelAdapter personIdentity) { rpcCallAsyncCommonDelete(personIdentity); } public static void rpcCallDeletePerson(ModelAdapter person) { rpcCallAsyncCommonDelete(person); } public static ModelAdapter rpcCallFindPersonById(String personId) { List remoteIpList = getRpcCallIp(); for (String remoteIp : remoteIpList) { SocketUtil socketUtil = new SocketUtil(); try { Map requestMap = new HashMap<>(); requestMap.put(Person.id, personId); requestMap.put(PersonSocket.requestType, PersonSocket.findPersonById); socketUtil.openSocket(remoteIp, Constants.personServerPort); socketUtil.writeMap(requestMap); Map responseMap = socketUtil.readJsonAsMap(); int modelMapByteArrayLength = Integer.parseInt(responseMap.get(PersonSocket.modelMapByteArrayLength)); if (modelMapByteArrayLength > 0) { byte[] personByteArray = new byte[modelMapByteArrayLength]; socketUtil.readFullByteArray(personByteArray); Map personModel = (Map) ObjectUtil.toObject(personByteArray);//SerializationUtils.deserialize(personByteArray); if (personModel != null) { // System1.out.println("SocketUtil.rpcCallFindPersonById " + personModel); ModelAdapter person = new ModelAdapter(); person.model = personModel; byte[] camera_image_path_byte_array = (byte[]) person.model.get(PersonSocket.camera_image_path_byte_array); if (camera_image_path_byte_array != null && camera_image_path_byte_array.length > 0) { person.setBlob(Person.camera_image_path, camera_image_path_byte_array); } PersonManager.savePerson(person); return person; } } else { // System1.out.println("SocketUtil.rpcCallFindPersonById"); } } catch (Exception e) { e.printStackTrace(); } finally { socketUtil.close(); } } return null; } public static Map rpcCall(String ip, int port, Map requestMap) { SocketUtil socketUtil = new SocketUtil(); try { socketUtil.openSocket(ip, port); socketUtil.writeMap(requestMap); return socketUtil.readJsonAsMap(); } catch (Exception e) { e.printStackTrace(); } finally { socketUtil.close(); } return null; } public static Map rpcCallDownload(String ip, int port, String camera_image_path) { SocketUtil socketUtil = new SocketUtil(); try { socketUtil.openSocket(ip, port); Map requestMap = new HashMap<>(); requestMap.put(Person.camera_image_path, camera_image_path); socketUtil.writeMap(requestMap); Map responseMap = socketUtil.readMap(); if (Constants.TRUE.equals(responseMap.get(Constants.SUCCESS))) { int length = Integer.parseInt(responseMap.get(Constants.LENGTH) + ""); byte[] fileBuffer = new byte[length]; socketUtil.readFullByteArray(fileBuffer); FileWriter fileWriter = new FileWriter(camera_image_path); IOUtils.write(fileBuffer, fileWriter); fileWriter.flush(); fileWriter.close(); System1.out.println("SocketUtil.rpcCallDownload camera_image_path=" + camera_image_path); } } catch (Exception e) { e.printStackTrace(); } finally { socketUtil.close(); } return null; } public static void rpcCallAsyncDeleteBusinessRule(ModelAdapter business) { rpcCallAsyncCommonDelete(business); } public static void rpcCallSaveBusinessRule(ModelAdapter business) { rpcCallAsyncCommonSave(business); } public static void rpcCallDeleteTimeRule(ModelAdapter timeRule) { rpcCallAsyncCommonDelete(timeRule); } public Map readJsonAsMap() throws Exception { String json; int len; while ((len = dataInputStream.read(buffer)) != -1) { for (int i = 0; i < len; i++) { if (buffer[i] == '\0') { Map messageMap = new HashMap<>(); try { byte[] jsonByteArray = byteArrayOutputStream.toByteArray(); byteArrayOutputStream.reset(); json = new String(jsonByteArray, 0, jsonByteArray.length); json = json.substring(0, json.lastIndexOf("}") + 1); if (json.length() > 3) { JsonParser parser = new JsonParser(); boolean isJSON = true; JsonElement element = null; try { element = parser.parse(json); } catch (JsonParseException e) { System1.out.println("exception: " + e); isJSON = false; } if (isJSON && element != null) { JsonObject obj = element.getAsJsonObject(); for (Map.Entry entry : obj.entrySet()) { if (!(entry.getValue() instanceof JsonNull)) { messageMap.put(entry.getKey(), entry.getValue().getAsString()); } } } } } catch (Exception e) { e.printStackTrace(); } return messageMap; } else { byteArrayOutputStream.write(buffer[i]); } } } throw new RuntimeException("inputStream.read(buffer) == -1"); } public void close() { try { if (socket != null) { socket.close(); socket = null; } if (byteArrayOutputStream != null) { byteArrayOutputStream.close(); byteArrayOutputStream = null; } if (mBufferManager != null) { mBufferManager.close(); mBufferManager = null; } } catch (IOException e) { } } public void setSocket(Socket socket) throws Exception { this.socket = socket; this.remoteIp = (((InetSocketAddress) socket.getRemoteSocketAddress()).getAddress()).toString().replace("/", ""); BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream()); BufferedOutputStream outputStream = new BufferedOutputStream(socket.getOutputStream()); dataInputStream = new DataInputStream(socket.getInputStream()); dataOutStream = new DataOutputStream(outputStream); if (byteArrayOutputStream == null) { byteArrayOutputStream = new ByteArrayOutputStream(); } byteArrayOutputStream.reset(); } public void openSocket(String ip, int port) throws Exception { close(); SystemClock.sleep(Constants.reconnectInMilliSeconds); socket = new Socket(); socket.connect(new InetSocketAddress(ip, port), 10000); this.setSocket(socket); } public void writeMessage(String key, String value) throws Exception { JsonObject jsonObj = new JsonObject(); jsonObj.addProperty(key, value); dataOutStream.write(jsonObj.toString().getBytes()); dataOutStream.write('\0'); dataOutStream.flush(); } public void writeMessage(Map keyValues) throws Exception { JsonObject jsonObj = new JsonObject(); for (Map.Entry entry : keyValues.entrySet()) { jsonObj.addProperty(entry.getKey(), entry.getValue()); } dataOutStream.write(jsonObj.toString().getBytes()); dataOutStream.write('\0'); dataOutStream.flush(); } public void writeByteArray(byte[] byteArray) throws Exception { if (byteArray != null) { dataOutStream.write(byteArray); dataOutStream.flush(); } } public void readFullByteArray(byte[] imageBuff) throws Exception { dataInputStream.readFully(imageBuff, 0, imageBuff.length); } public void readFullByteArray(byte[] imageBuff, int length) throws Exception { dataInputStream.readFully(imageBuff, 0, length); } public void readFrameInfo() throws Exception { Map messageMap = this.readJsonAsMap(); int length = Integer.parseInt(messageMap.get("length")); int width = Integer.parseInt(messageMap.get("width")); int height = Integer.parseInt(messageMap.get("height")); imageBuff = new byte[length]; mBufferManager = new YuvToJpgFrameBufferManager(length, width, height); } public boolean readBitmapHeader(Map frameInfo) { boolean success = frameInfo.get(Constants.SUCCESS).equals(Constants.TRUE); if (success) { int length = Integer.parseInt(frameInfo.get("length")); int width = Integer.parseInt(frameInfo.get("width")); int height = Integer.parseInt(frameInfo.get("height")); imageBuff = new byte[length]; mBufferManager = new YuvToJpgFrameBufferManager(length, width, height); } return success; } public boolean readBitmapHeader() throws Exception { return readBitmapHeader((Map) this.readObject()); } public void setBitmapListener(BitmapListener cameraDataListener) { mBufferManager.setOnDataListener(cameraDataListener); this.cameraDataListener = cameraDataListener; } public Object readObject() throws Exception { return readJsonAsMap(); } public boolean remoteIpAllowed() { return true; } public boolean remoteIpAllowed(Map map) { if (remoteIpAllowed()) { map.put(Constants.SUCCESS, Constants.TRUE); } else { map.put(Constants.SUCCESS, Constants.FALSE); } return true; } public boolean writeBitmapHeader() throws Exception { boolean success; Map map = new HashMap<>(); if (remoteIpAllowed()) { map.put(Constants.SUCCESS, Constants.TRUE); map.put("type", "data"); map.put("length", "460800"); map.put("width", "640"); map.put("height", "480"); map.put("rotation", "270"); success = true; } else { map.put(Constants.SUCCESS, Constants.FALSE); success = false; } writeMessage(map); return success; } public void writeMap(Map map) throws Exception { writeMessage(map); } public Map readMap() throws Exception { return (Map) readObject(); } public void writeResponseSuccess() throws Exception { Map responseMap = new HashMap<>(); responseMap.put(Constants.SUCCESS, Constants.TRUE); writeMap(responseMap); } public ModelAdapter readModelAdapterMap(Map requestMap) throws Exception { int modelMapByteArrayLength = Integer.parseInt(requestMap.get(PersonSocket.modelMapByteArrayLength)); if (modelMapByteArrayLength > 0) { byte[] personByteArray = new byte[modelMapByteArrayLength]; readFullByteArray(personByteArray); Map modelMap = (Map) ObjectUtil.toObject(personByteArray); if (modelMap != null) { ModelAdapter modelAdapter = new ModelAdapter(); modelAdapter.model = modelMap; return modelAdapter; } } return null; } }