diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
index 5e796d755..6ad8e7e04 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -28,6 +28,8 @@ public class VideoManagerConstants {
 
 	public static final String PLATFORM_REGISTER_PREFIX = "VMP_platform_register_";
 
+	public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_platform_register_info_";
+
 	public static final String Pattern_Topic = "VMP_keeplive_platform_";
 
 	public static final String EVENT_ONLINE_REGISTER = "1";
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
index eae454779..106b3cf29 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -45,11 +45,11 @@ public class SipPlatformRunner implements CommandLineRunner {
             ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch();
 
             parentPlatformCatch.setParentPlatform(parentPlatform);
-            parentPlatformCatch.setId(parentPlatform.getDeviceGBId());
+            parentPlatformCatch.setId(parentPlatform.getServerGBId());
             redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
 
             // 发送平台未注册消息
-            publisher.platformNotRegisterEventPublish(parentPlatform.getDeviceGBId());
+            publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId());
         }
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
index 994039a08..6c429f265 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
@@ -10,6 +10,8 @@ public class ParentPlatformCatch {
     // 注册未回复次数
     private int registerAliveReply;
 
+    private String callId;
+
     private ParentPlatform parentPlatform;
 
     public String getId() {
@@ -43,4 +45,12 @@ public class ParentPlatformCatch {
     public void setParentPlatform(ParentPlatform parentPlatform) {
         this.parentPlatform = parentPlatform;
     }
+
+    public String getCallId() {
+        return callId;
+    }
+
+    public void setCallId(String callId) {
+        this.callId = callId;
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/Codec.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/Codec.java
new file mode 100755
index 000000000..4ab6f8f8a
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/Codec.java
@@ -0,0 +1,65 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2010 Yohann Martineau 
+*/
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+public class Codec {
+
+    private int payloadType;
+    private String name;
+
+    public int getPayloadType() {
+        return payloadType;
+    }
+
+    public void setPayloadType(int payloadType) {
+        this.payloadType = payloadType;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Codec)) {
+            return false;
+        }
+        Codec codec = (Codec)obj;
+        if (codec.getName() == null) {
+            return name == null;
+        }
+        return codec.getName().equalsIgnoreCase(name);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(RFC4566_28181.TYPE_ATTRIBUTE).append(RFC4566_28181.SEPARATOR);
+        buf.append(RFC4566_28181.ATTR_RTPMAP).append(RFC4566_28181.ATTR_SEPARATOR);
+        buf.append(payloadType).append(" ").append(name).append("/");
+        buf.append(9000).append("\r\n");
+        return buf.toString();
+    }
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/MediaDescription.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/MediaDescription.java
new file mode 100755
index 000000000..50f361f1f
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/MediaDescription.java
@@ -0,0 +1,123 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2007, 2008, 2009, 2010 Yohann Martineau 
+ */
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.Hashtable;
+import java.util.List;
+
+public class MediaDescription {
+
+    private String type;
+    private InetAddress ipAddress;
+    // attributes not codec-related
+    private Hashtable<String, String> attributes;
+    private int port;
+    private List<Codec> codecs;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Hashtable<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Hashtable<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    public InetAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(InetAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public List<Codec> getCodecs() {
+        return codecs;
+    }
+
+    public void setCodecs(List<Codec> codecs) {
+        this.codecs = codecs;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(RFC4566_28181.TYPE_MEDIA).append(RFC4566_28181.SEPARATOR);
+        buf.append(type).append(" ").append(port);
+        buf.append(" RTP/AVP");
+        if (codecs != null) {
+            for (Codec codec: codecs) {
+                buf.append(" ");
+                buf.append(codec.getPayloadType());
+            }
+            buf.append("\r\n");
+        }
+        if (ipAddress != null) {
+            int ipVersion;
+            if (ipAddress instanceof Inet4Address) {
+                ipVersion = 4;
+            } else if (ipAddress instanceof Inet6Address) {
+                ipVersion = 6;
+            } else {
+                throw new RuntimeException("unknown ip version: " + ipAddress);
+            }
+            buf.append(RFC4566_28181.TYPE_CONNECTION).append(RFC4566_28181.SEPARATOR);
+            buf.append("IN IP").append(ipVersion).append(" ");
+            buf.append(ipAddress.getHostAddress()).append("\r\n");
+        }
+        if (codecs != null) {
+            for (Codec codec: codecs) {
+                buf.append(codec.toString());
+            }
+        }
+
+        if (attributes != null) {
+            for (String attributeName: attributes.keySet()) {
+                buf.append(RFC4566_28181.TYPE_ATTRIBUTE).append(RFC4566_28181.SEPARATOR);
+                buf.append(attributeName);
+                String attributeValue = attributes.get(attributeName);
+                if (attributeValue != null && !"".equals(attributeValue.trim())) {
+                    buf.append(":").append(attributeValue);
+                }
+                buf.append("\r\n");
+            }
+        }
+        return buf.toString();
+    }
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/RFC4566_28181.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/RFC4566_28181.java
new file mode 100755
index 000000000..dd6019be8
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/RFC4566_28181.java
@@ -0,0 +1,51 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2007, 2008, 2009, 2010 Yohann Martineau 
+*/
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+public class RFC4566_28181 {
+
+    public static final char VERSION = '0';
+    
+    public static final char TYPE_VERSION    = 'v';
+    public static final char TYPE_ORIGIN     = 'o';
+    public static final char TYPE_SUBJECT    = 's';
+    public static final char TYPE_INFO       = 'i';
+    public static final char TYPE_URI        = 'u';
+    public static final char TYPE_EMAIL      = 'e';
+    public static final char TYPE_PHONE      = 'p';
+    public static final char TYPE_CONNECTION = 'c';
+    public static final char TYPE_BANDWITH   = 'b';
+    public static final char TYPE_TIME       = 't';
+    public static final char TYPE_REPEAT     = 'r';
+    public static final char TYPE_ZONE       = 'z';
+    public static final char TYPE_KEY        = 'k';
+    public static final char TYPE_ATTRIBUTE  = 'a';
+    public static final char TYPE_MEDIA      = 'm';
+    public static final char TYPE_SSRC       = 'y';
+    public static final char TYPE_MEDIA_DES  = 'f';
+
+    public static final char SEPARATOR       = '=';
+    public static final char ATTR_SEPARATOR  = ':';
+
+    public static final String MEDIA_AUDIO   = "audio";
+
+    public static final String ATTR_RTPMAP   = "rtpmap";
+    public static final String ATTR_SENDRECV = "sendrecv";
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpLine.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpLine.java
new file mode 100755
index 000000000..2d573382f
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpLine.java
@@ -0,0 +1,38 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2007, 2008, 2009, 2010 Yohann Martineau 
+*/
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+public class SdpLine {
+    private char type;
+    private String value;
+    public char getType() {
+        return type;
+    }
+    public void setType(char type) {
+        this.type = type;
+    }
+    public String getValue() {
+        return value;
+    }
+    public void setValue(String value) {
+        this.value = value;
+    }
+    
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpParser.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpParser.java
new file mode 100755
index 000000000..fb8d499f3
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpParser.java
@@ -0,0 +1,230 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2007, 2008, 2009, 2010 Yohann Martineau 
+*/
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+public class SdpParser {
+
+	public SessionDescription parse(byte[] body) throws IOException {
+		if (body == null || body.length == 0) {
+			return null;
+		}
+		ByteArrayInputStream in = new ByteArrayInputStream(body);
+		InputStreamReader inputStreamReader = new InputStreamReader(in);
+		BufferedReader reader = new BufferedReader(inputStreamReader);
+		SessionDescription sessionDescription = new SessionDescription();
+		
+		//version
+		
+		String line = reader.readLine();
+		if (line.length() < 3) {
+			return null;
+		}
+		if (line.charAt(0) != RFC4566_28181.TYPE_VERSION
+				|| line.charAt(1) != RFC4566_28181.SEPARATOR
+				|| line.charAt(2) != RFC4566_28181.VERSION) {
+			return null;
+		}
+
+		//origin
+		
+		line = reader.readLine();
+		if (line.length() < 3) {
+			return null;
+		}
+		if (line.charAt(0) != RFC4566_28181.TYPE_ORIGIN
+				|| line.charAt(1) != RFC4566_28181.SEPARATOR) {
+			return null;
+		}
+		line = line.substring(2);
+		String[] originArr = line.split(" ");
+		if (originArr == null || originArr.length != 6) {
+			return null;
+		}
+		sessionDescription.setUsername(originArr[0]);
+		sessionDescription.setId(Long.parseLong(originArr[1]));
+		sessionDescription.setVersion(Long.parseLong(originArr[2]));
+		sessionDescription.setIpAddress(InetAddress.getByName(originArr[5]));
+
+		//name
+		
+		line = reader.readLine();
+		if (line.length() < 3) {
+			return null;
+		}
+		if (line.charAt(0) != RFC4566_28181.TYPE_SUBJECT
+				|| line.charAt(1) != RFC4566_28181.SEPARATOR) {
+			return null;
+		}
+		sessionDescription.setName(line.substring(2));
+		
+		//session connection and attributes
+        Hashtable<String, String> sessionAttributes = new Hashtable<String, String>();
+        sessionDescription.setAttributes(sessionAttributes);
+		
+		while ((line = reader.readLine()) != null
+				&& line.charAt(0) != RFC4566_28181.TYPE_MEDIA) {
+			if (line.length() > 3
+					&& line.charAt(0) == RFC4566_28181.TYPE_CONNECTION
+					&& line.charAt(1) == RFC4566_28181.SEPARATOR) {
+				String connection = parseConnection(line.substring(2));
+				if (connection == null) {
+					continue;
+				}
+				sessionDescription.setIpAddress(InetAddress.getByName(connection));
+			} else if (line.length() > 3
+                    && line.charAt(0) == RFC4566_28181.TYPE_ATTRIBUTE
+                    && line.charAt(1) == RFC4566_28181.SEPARATOR) {
+                String value = line.substring(2);
+                int pos = value.indexOf(RFC4566_28181.ATTR_SEPARATOR);
+                if (pos > -1) {
+                    sessionAttributes.put(value.substring(0, pos),
+                            value.substring(pos + 1));
+                } else {
+                    sessionAttributes.put(value, "");
+                }
+            }
+		}
+		if (line == null) {
+			return null;
+		}
+		//we are at the first media line
+        
+        ArrayList<SdpLine> mediaLines = new ArrayList<SdpLine>();
+        do {
+            if (line.length() < 2) {
+                return null;
+            }
+            if (line.charAt(1) != RFC4566_28181.SEPARATOR) {
+                return null;
+            }
+            if (line.charAt(0) == RFC4566_28181.TYPE_SSRC) {
+                sessionDescription.setSsrc(line.length() >=2 ?line.substring(2):"");
+            }else if (line.charAt(0) == RFC4566_28181.TYPE_MEDIA_DES) {
+                sessionDescription.setGbMediaDescriptions(line.length() >=2 ?line.substring(2):"");
+            }else {
+                SdpLine mediaLine = new SdpLine();
+                mediaLine.setType(line.charAt(0));
+                mediaLine.setValue(line.substring(2));
+                mediaLines.add(mediaLine);
+            }
+
+        }
+        while ((line = reader.readLine()) != null );
+        
+        ArrayList<MediaDescription> mediaDescriptions = new ArrayList<MediaDescription>();
+        sessionDescription.setMediaDescriptions(mediaDescriptions);
+        
+        for (SdpLine sdpLine : mediaLines) {
+            MediaDescription mediaDescription;
+            if (sdpLine.getType() == RFC4566_28181.TYPE_MEDIA) {
+                String[] mediaArr = sdpLine.getValue().split(" ");
+                if (mediaArr == null || mediaArr.length < 4) {
+                    return null;
+                }
+                mediaDescription = new MediaDescription();
+                mediaDescription.setType(mediaArr[0]);
+                //TODO manage port range
+                mediaDescription.setPort(Integer.parseInt(mediaArr[1]));
+                mediaDescription.setAttributes(new Hashtable<String, String>());
+                List<Codec> codecs = new ArrayList<Codec>();
+                for (int i = 3; i < mediaArr.length; ++i) {
+                    int payloadType = Integer.parseInt(mediaArr[i]);
+                    Codec codec = new Codec();
+                    codec.setPayloadType(payloadType);
+                    codec.setName("unsupported");
+                    codecs.add(codec);
+                }
+                mediaDescription.setCodecs(codecs);
+                mediaDescriptions.add(mediaDescription);
+            } else {
+                mediaDescription = mediaDescriptions.get(mediaDescriptions.size() - 1);
+                String sdpLineValue = sdpLine.getValue();
+                if (sdpLine.getType() == RFC4566_28181.TYPE_CONNECTION) {
+                    String ipAddress = parseConnection(sdpLineValue);
+                    mediaDescription.setIpAddress(InetAddress.getByName(ipAddress));
+                } else if (sdpLine.getType() == RFC4566_28181.TYPE_ATTRIBUTE) {
+                    Hashtable<String, String> attributes = mediaDescription.getAttributes();
+                    int pos = sdpLineValue.indexOf(RFC4566_28181.ATTR_SEPARATOR);
+                    if (pos > -1) {
+                        String name = sdpLineValue.substring(0, pos);
+                        String value = sdpLineValue.substring(pos + 1);
+                        pos = value.indexOf(" ");
+                        if (pos > -1) {
+                            int payloadType;
+                            try {
+                                payloadType = Integer.parseInt(value.substring(0, pos));
+                                List<Codec> codecs = mediaDescription.getCodecs();
+                                for (Codec codec: codecs) {
+                                    if (codec.getPayloadType() == payloadType) {
+                                        value = value.substring(pos + 1);
+                                        pos = value.indexOf("/");
+                                        if (pos > -1) {
+                                            value = value.substring(0, pos);
+                                            codec.setName(value);
+                                        }
+                                        break;
+                                    }
+                                }
+                            } catch (NumberFormatException e) {
+                                attributes.put(name, value);
+                            }
+                        } else {
+                            attributes.put(name, value);
+                        }
+                    } else {
+                        attributes.put(sdpLineValue, "");
+                    }
+                }
+            }
+        }
+        sessionDescription.setMediaDescriptions(mediaDescriptions);
+
+        for (MediaDescription description : mediaDescriptions) {
+            if (description.getIpAddress() == null) {
+                InetAddress sessionAddress = sessionDescription.getIpAddress();
+                if (sessionAddress == null) {
+                    return null;
+                }
+                description.setIpAddress(sessionAddress);
+            }
+        }
+
+
+		return sessionDescription;
+	}
+	
+	private String parseConnection(String line) {
+		String[] connectionArr = line.split(" ");
+		if (connectionArr == null || connectionArr.length != 3) {
+			return null;
+		}
+		return connectionArr[2];
+	}
+	
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SessionDescription.java b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SessionDescription.java
new file mode 100755
index 000000000..ad68099b9
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SessionDescription.java
@@ -0,0 +1,162 @@
+/*
+    This file is part of Peers, a java SIP softphone.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    
+    Copyright 2007, 2008, 2009, 2010 Yohann Martineau 
+*/
+
+package com.genersoft.iot.vmp.gb28181.sdp;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.Hashtable;
+import java.util.List;
+
+public class SessionDescription {
+
+	private long id;
+	private long version;
+	private String name;
+	private String username;
+	private InetAddress ipAddress;
+	private List<MediaDescription> mediaDescriptions;
+    private Hashtable<String, String> attributes;
+    private String ssrc;
+    private String gbMediaDescriptions;
+
+    public SessionDescription() {
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public InetAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(InetAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public List<MediaDescription> getMediaDescriptions() {
+        return mediaDescriptions;
+    }
+
+    public void setMediaDescriptions(List<MediaDescription> mediaDescriptions) {
+        this.mediaDescriptions = mediaDescriptions;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long version) {
+        this.version = version;
+    }
+
+    public Hashtable<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Hashtable<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    public String getSsrc() {
+        return ssrc;
+    }
+
+    public void setSsrc(String ssrc) {
+        this.ssrc = ssrc;
+    }
+
+    public String getGbMediaDescriptions() {
+        return gbMediaDescriptions;
+    }
+
+    public void setGbMediaDescriptions(String gbMediaDescriptions) {
+        this.gbMediaDescriptions = gbMediaDescriptions;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("v=0\r\n");
+        buf.append("o=").append(username).append(" ").append(id);
+        buf.append(" ").append(version);
+        int ipVersion;
+        if (ipAddress instanceof Inet4Address) {
+            ipVersion = 4;
+        } else if (ipAddress instanceof Inet6Address) {
+            ipVersion = 6;
+        } else {
+            throw new RuntimeException("unknown ip version: " + ipAddress);
+        }
+        buf.append(" IN IP").append(ipVersion).append(" ");
+        String hostAddress = ipAddress.getHostAddress();
+        buf.append(hostAddress).append("\r\n");
+        buf.append("s=").append(name).append("\r\n");
+        buf.append("c=IN IP").append(ipVersion).append(" ");
+        buf.append(hostAddress).append("\r\n");
+        buf.append("t=0 0\r\n");
+        if (attributes != null){
+            for (String attributeName: attributes.keySet()) {
+                String attributeValue = attributes.get(attributeName);
+                buf.append("a=").append(attributeName);
+                if (attributeValue != null && !"".equals(attributeValue.trim())) {
+                    buf.append(":");
+                    buf.append(attributeValue);
+                    buf.append("\r\n");
+                }
+            }
+        }
+        if (mediaDescriptions != null){
+            for (MediaDescription mediaDescription: mediaDescriptions) {
+                buf.append(mediaDescription.toString());
+            }
+        }
+
+        if (ssrc != null){
+            buf.append("y=").append(ssrc).append("\r\n");
+        }
+        if (gbMediaDescriptions != null){
+            buf.append("f=").append(gbMediaDescriptions).append("\r\n");
+        }
+        return buf.toString();
+    }
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
index eb81ed3f9..75db91073 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -119,6 +119,9 @@ public class SIPProcessorFactory {
 			processor.setRequestEvent(evt);
 			processor.setTcpSipProvider(getTcpSipProvider());
 			processor.setUdpSipProvider(getUdpSipProvider());
+
+			processor.setCmderFroPlatform(cmderFroPlatform);
+			processor.setStorager(storager);
 			return processor;
 		} else if (Request.REGISTER.equals(method)) {
 			RegisterRequestProcessor processor = new RegisterRequestProcessor();
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
index 2ba84acf7..b038ec29e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -70,7 +70,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
     @Override
     public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
         parentPlatform.setExpires("0");
-        ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId());
+        ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
         if (parentPlatformCatch != null) {
             parentPlatformCatch.setParentPlatform(parentPlatform);
             redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
@@ -86,11 +86,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
 
             if (www == null ) {
                 request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, 1L, null, null);
+                // 将 callid 写入缓存, 等注册成功可以更新状态
+                CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
+                redisCatchStorage.updatePlatformRegisterInfo(callIdHeader.getCallId(), parentPlatform.getServerGBId());
+
+                sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (event)->{
+                    redisCatchStorage.delPlatformRegisterInfo(callIdHeader.getCallId());
+                    if (errorEvent != null) {
+                        errorEvent.response(event);
+                    }
+                });
             }else {
                 request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, null, null, callId, www);
             }
 
-            transmitRequest(parentPlatform, request, errorEvent, okEvent);
+            transmitRequest(parentPlatform, request, null, okEvent);
             return true;
         } catch (ParseException e) {
             e.printStackTrace();
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
index ab70a5ede..c15b7ca23 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -1,71 +1,231 @@
 package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
 
+import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.SipException;
+import javax.sip.address.SipURI;
+import javax.sip.header.ContentTypeHeader;
+import javax.sip.header.FromHeader;
+import javax.sip.header.SubjectHeader;
+import javax.sip.message.Request;
+import javax.sip.message.Response;
 
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.sdp.Codec;
+import com.genersoft.iot.vmp.gb28181.sdp.MediaDescription;
+import com.genersoft.iot.vmp.gb28181.sdp.SdpParser;
+import com.genersoft.iot.vmp.gb28181.sdp.SessionDescription;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import gov.nist.javax.sip.address.AddressImpl;
+import gov.nist.javax.sip.address.SipUri;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.List;
 
 /**    
  * @Description:处理INVITE请求
- * @author: swwheihei
- * @date:   2020年5月3日 下午4:43:52     
+ * @author: panll
+ * @date:   2021年1月14日
  */
 public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
 
+	private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
+
+	private SIPCommanderFroPlatform cmderFroPlatform;
+
+	private IVideoManagerStorager storager;
+
 	/**
 	 * 处理invite请求
 	 * 
-	 * @param request
+	 * @param evt
 	 *            请求消息
 	 */ 
 	@Override
 	public void process(RequestEvent evt) {
-		// TODO 优先级99 Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令
-//		Request request = requestEvent.getRequest();
-//
-//		try {
-//			// 发送100 Trying
-//			ServerTransaction serverTransaction = getServerTransaction(requestEvent);
-//			// 查询目标地址
-//			URI reqUri = request.getRequestURI();
-//			URI contactURI = currUser.get(reqUri);
-//
-//			System.out.println("processInvite rqStr=" + reqUri + " contact=" + contactURI);
-//
-//			// 根据Request uri来路由,后续的响应消息通过VIA来路由
-//			Request cliReq = messageFactory.createRequest(request.toString());
-//			cliReq.setRequestURI(contactURI);
-//
-//			HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory();
-//			Via callerVia = (Via) request.getHeader(Via.NAME);
-//			Via via = (Via) headerFactory.createViaHeader(SIPMain.ip, SIPMain.port, "UDP",
-//					callerVia.getBranch() + "sipphone");
-//
-//			cliReq.removeHeader(Via.NAME);
-//			cliReq.addHeader(via);
-//
-//			// 更新contact的地址
-//			ContactHeader contactHeader = headerFactory.createContactHeader();
-//			Address address = SipFactory.getInstance().createAddressFactory()
-//					.createAddress("sip:sipsoft@" + SIPMain.ip + ":" + SIPMain.port);
-//			contactHeader.setAddress(address);
-//			contactHeader.setExpires(3600);
-//			cliReq.setHeader(contactHeader);
-//
-//			clientTransactionId = sipProvider.getNewClientTransaction(cliReq);
-//			clientTransactionId.sendRequest();
-//
-//			System.out.println("processInvite clientTransactionId=" + clientTransactionId.toString());
-//
-//			System.out.println("send invite to callee: " + cliReq);
-//		} catch (TransactionUnavailableException e1) {
-//			e1.printStackTrace();
-//		} catch (SipException e) {
-//			e.printStackTrace();
-//		} catch (ParseException e) {
-//			e.printStackTrace();
-//		} catch (Exception e) {
-//			e.printStackTrace();
-//		}
+		//  Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令
+		try {
+			Request request = evt.getRequest();
+			SipURI sipURI = (SipURI) request.getRequestURI();
+			String channelId = sipURI.getUser();
+			String platformId = null;
+//			SubjectHeader subjectHeader = (SubjectHeader)request.getHeader(SubjectHeader.NAME);
+//			// 查询通道是否存在 不存在回复404
+//			if (subjectHeader != null) { // 存在则从subjectHeader 获取平台信息
+//				String subject = subjectHeader.getSubject();
+//				if (subject != null) {
+//					String[] info1 = subject.split(",");
+//					if (info1 != null && info1 .length == 2) {
+//						String[] info2 = info1[1].split(":");
+//						if (info2 != null && info2.length == 2) {
+//							platformId = info2[0];
+//						}
+//					}
+//				}
+//			}
+
+			FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
+			AddressImpl address = (AddressImpl) fromHeader.getAddress();
+			SipUri uri = (SipUri) address.getURI();
+			platformId = uri.getUser();
+
+//			if (platformId == null) { // 不存在则从fromHeader 获取平台信息
+//				FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
+//				platformId = fromHeader.getName();
+//			}
+			if (platformId == null || channelId == null) {
+				response400Ack(evt); // 参数不全, 发400,请求错误
+				return;
+			}
+			// 查询平台下是否有该通道
+			DeviceChannel channel = storager.queryChannelInParentPlatform(platformId, channelId);
+			if (channel == null) {
+				response404Ack(evt); // 通道不存在,发404,资源不存在
+				return;
+			}else {
+				response100Ack(evt); // 通道存在,发100,trying
+			}
+			// 解析sdp消息
+			byte[] sdpByteArray = request.getRawContent();
+			SdpParser sdpParser = new SdpParser(); // TODO keng
+			SessionDescription sdp = sdpParser.parse(sdpByteArray);
+			//  获取支持的格式
+			List<MediaDescription> mediaDescriptions = sdp.getMediaDescriptions();
+			// 查看是否支持PS 负载96
+			String ip = null;
+			int port = -1;
+			for (MediaDescription mediaDescription : mediaDescriptions) {
+
+				List<Codec> codecs = mediaDescription.getCodecs();
+				for (Codec codec : codecs) {
+					if("96".equals(codec.getPayloadType()) || "PS".equals(codec.getName()) || "ps".equals(codec.getName())) {
+						ip = mediaDescription.getIpAddress().getHostName();
+						port = mediaDescription.getPort();
+						break;
+					}
+				}
+			}
+			if (ip == null || port == -1) { // TODO 没有合适的视频流格式, 可配置是否使用第一个media信息
+				if (mediaDescriptions.size() > 0) {
+					ip = mediaDescriptions.get(0).getIpAddress().getHostName();
+					port = mediaDescriptions.get(0).getPort();
+				}
+			}
+
+			if (ip == null || port == -1) {
+				response488Ack(evt);
+				return;
+			}
+
+
+			String ssrc = sdp.getSsrc();
+			// 通知下级推流,
+			// 查找合适的端口推流,
+			// 发送 200ok
+			// 收到ack后调用推流接口
+
+
+
+
+		} catch (SipException | InvalidArgumentException | ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			logger.warn("sdp解析错误");
+			e.printStackTrace();
+		}
+
 	}
 
+	/***
+	 * 回复100 trying
+	 * @param evt
+	 * @throws SipException
+	 * @throws InvalidArgumentException
+	 * @throws ParseException
+	 */
+	private void response100Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
+		Response response = getMessageFactory().createResponse(Response.TRYING, evt.getRequest());
+		getServerTransaction(evt).sendResponse(response);
+	}
+
+	/***
+	 * 回复404
+	 * @param evt
+	 * @throws SipException
+	 * @throws InvalidArgumentException
+	 * @throws ParseException
+	 */
+	private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
+		Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest());
+		getServerTransaction(evt).sendResponse(response);
+	}
+
+	/***
+	 * 回复400
+	 * @param evt
+	 * @throws SipException
+	 * @throws InvalidArgumentException
+	 * @throws ParseException
+	 */
+	private void response400Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
+		Response response = getMessageFactory().createResponse(Response.BAD_REQUEST, evt.getRequest());
+		getServerTransaction(evt).sendResponse(response);
+	}
+
+	/***
+	 * 回复488
+	 * @param evt
+	 * @throws SipException
+	 * @throws InvalidArgumentException
+	 * @throws ParseException
+	 */
+	private void response488Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
+		Response response = getMessageFactory().createResponse(Response.NOT_ACCEPTABLE_HERE, evt.getRequest());
+		getServerTransaction(evt).sendResponse(response);
+	}
+
+	/***
+	 * 回复200 OK
+	 * @param evt
+	 * @throws SipException
+	 * @throws InvalidArgumentException
+	 * @throws ParseException
+	 */
+	private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
+		Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
+		ContentTypeHeader contentTypeHeader = getHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
+		response.setContent(sdp, contentTypeHeader);
+		getServerTransaction(evt).sendResponse(response);
+	}
+
+
+
+
+
+
+
+
+
+
+	public SIPCommanderFroPlatform getCmderFroPlatform() {
+		return cmderFroPlatform;
+	}
+
+	public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) {
+		this.cmderFroPlatform = cmderFroPlatform;
+	}
+
+	public IVideoManagerStorager getStorager() {
+		return storager;
+	}
+
+	public void setStorager(IVideoManagerStorager storager) {
+		this.storager = storager;
+	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 9ad928d6f..06c4d686c 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -15,6 +15,8 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
+import gov.nist.javax.sip.address.AddressImpl;
+import gov.nist.javax.sip.address.SipUri;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
@@ -166,10 +168,15 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 			Element deviceIdElement = rootElement.element("DeviceID");
 			String deviceId = deviceIdElement.getText();
 			Element deviceListElement = rootElement.element("DeviceList");
+
+			FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
+			AddressImpl address = (AddressImpl) fromHeader.getAddress();
+			SipUri uri = (SipUri) address.getURI();
+			String platformId = uri.getUser();
 			// if (deviceListElement == null) { // 存在DeviceList则为响应 catalog, 不存在DeviceList则为查询请求
 			if (name == "Query") { // 区分是Response——查询响应,还是Query——查询请求
 					// TODO 后续将代码拆分
-				ParentPlatform parentPlatform = storager.queryParentPlatById(deviceId);
+				ParentPlatform parentPlatform = storager.queryParentPlatById(platformId);
 				if (parentPlatform == null) {
 					response404Ack(evt);
 					return;
@@ -179,9 +186,8 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 
 					Element snElement = rootElement.element("SN");
 					String sn = snElement.getText();
-					FromHeader fromHeader = (FromHeader)evt.getRequest().getHeader(FromHeader.NAME);
 					// 准备回复通道信息
-					List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getDeviceGBId());
+					List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
 					if (channelReduces.size() >0 ) {
 						for (ChannelReduce channelReduce : channelReduces) {
 							DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
@@ -499,7 +505,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 	}
 
 	/***
-	 * 回复200 OK
+	 * 回复404
 	 * @param evt
 	 * @throws SipException
 	 * @throws InvalidArgumentException
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
index bfe5e3f92..4716a3040 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
@@ -61,10 +61,14 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
 	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
 		// TODO Auto-generated method stub
 		Response response = evt.getResponse();
-		ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
-		SipUri uri = (SipUri)toHeader.getAddress().getURI();
-		String platformGBId = uri.getAuthority().getUser();
+		CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
+		String callId = callIdHeader.getCallId();
 
+		String platformGBId = redisCatchStorage.queryPlatformRegisterInfo(callId);
+		if (platformGBId == null) {
+			logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId ));
+			return;
+		}
 		logger.info(String.format("收到 %s 的注册/注销%S响应", platformGBId, response.getStatusCode() ));
 
 		ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId);
@@ -80,18 +84,13 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
 
 		if (response.getStatusCode() == 401) {
 			WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
-
-
-			CallIdHeader callIdHeader = (CallIdHeader)response.getHeader(CallIdHeader.NAME);
-			String callId = callIdHeader.getCallId();
-
 			sipCommanderForPlatform.register(parentPlatform, callId, www, null, null);
 		}else if (response.getStatusCode() == 200){
 			// 注册成功
 			logger.info(String.format("%s 注册成功", platformGBId ));
+			redisCatchStorage.delPlatformRegisterInfo(callId);
 			parentPlatform.setStatus(true);
 			storager.updateParentPlatform(parentPlatform);
-			//
 			redisCatchStorage.updatePlatformRegister(parentPlatform);
 
 			redisCatchStorage.updatePlatformKeepalive(parentPlatform);
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
index 2e55a00ec..49e557860 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -73,4 +73,9 @@ public interface IRedisCatchStorage {
 
     void delPlatformRegister(String platformGbId);
 
+    void updatePlatformRegisterInfo(String callId, String platformGbId);
+
+    String queryPlatformRegisterInfo(String callId);
+
+    void delPlatformRegisterInfo(String callId);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
index 970f7a478..7963109c8 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -233,4 +233,5 @@ public interface IVideoManagerStorager {
 	int delChannelForGB(String platformId, List<ChannelReduce> channelReduces);
 
 
+    DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
index 6d5d83b2a..257ca9eea 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
@@ -24,7 +24,7 @@ public interface ParentPlatformMapper {
     @Update("UPDATE parent_platform " +
             "SET enable=#{enable}, " +
             "name=#{name}," +
-            "serverGBId=#{serverGBId}," +
+            "deviceGBId=#{deviceGBId}," +
             "serverGBDomain=#{serverGBDomain}, " +
             "serverIP=#{serverIP}," +
             "serverPort=#{serverPort}, " +
@@ -39,13 +39,13 @@ public interface ParentPlatformMapper {
             "PTZEnable=#{PTZEnable}, " +
             "rtcp=#{rtcp}, " +
             "status=#{status} " +
-            "WHERE deviceGBId=#{deviceGBId}")
+            "WHERE serverGBId=#{serverGBId}")
     int updateParentPlatform(ParentPlatform parentPlatform);
 
-    @Delete("DELETE FROM parent_platform WHERE deviceGBId=#{deviceGBId}")
+    @Delete("DELETE FROM parent_platform WHERE serverGBId=#{serverGBId}")
     int delParentPlatform(ParentPlatform parentPlatform);
 
-    @Select("SELECT *,( SELECT count(0) FROM platform_gb_channel pc WHERE pc.platformId = pp.deviceGBId) as channelCount FROM parent_platform pp ")
+    @Select("SELECT *,( SELECT count(0) FROM platform_gb_channel pc WHERE pc.platformId = pp.serverGBId) as channelCount FROM parent_platform pp ")
     List<ParentPlatform> getParentPlatformList();
 
     @Select("SELECT * FROM parent_platform WHERE enable=#{enable}")
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
index cbc56fc3c..a5ee2755a 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
@@ -1,5 +1,6 @@
 package com.genersoft.iot.vmp.storager.dao;
 
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Insert;
@@ -39,4 +40,9 @@ public interface PatformChannelMapper {
             "DELETE FROM platform_gb_channel WHERE platformId='${platformId}'"  +
             "</script>")
     int cleanChannelForGB(String platformId);
+
+
+    @Select("SELECT * FROM device_channel WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE " +
+            "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'")
+    DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
index 63abc80d2..960e72823 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -169,13 +169,13 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
 
     @Override
     public void updatePlatformKeepalive(ParentPlatform parentPlatform) {
-        String key = VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX + parentPlatform.getDeviceGBId();
+        String key = VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX + parentPlatform.getServerGBId();
         redis.set(key, "", Integer.parseInt(parentPlatform.getKeepTimeout()));
     }
 
     @Override
     public void updatePlatformRegister(ParentPlatform parentPlatform) {
-        String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + parentPlatform.getDeviceGBId();
+        String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + parentPlatform.getServerGBId();
         redis.set(key, "", Integer.parseInt(parentPlatform.getExpires()));
     }
 
@@ -198,4 +198,22 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
     public void delPlatformRegister(String platformGbId) {
         redis.del(VideoManagerConstants.PLATFORM_REGISTER_PREFIX + platformGbId);
     }
+
+
+    @Override
+    public void updatePlatformRegisterInfo(String callId, String platformGbId) {
+        String key = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + callId;
+        redis.set(key, platformGbId);
+    }
+
+
+    @Override
+    public String queryPlatformRegisterInfo(String callId) {
+        return (String)redis.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + callId);
+    }
+
+    @Override
+    public void delPlatformRegisterInfo(String callId) {
+        redis.del(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + callId);
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
index 4547d76c3..aa83e3d10 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -254,7 +254,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
 	public boolean deleteParentPlatform(ParentPlatform parentPlatform) {
 		int result = platformMapper.delParentPlatform(parentPlatform);
 		// 删除关联的通道
-		patformChannelMapper.cleanChannelForGB(parentPlatform.getDeviceGBId());
+		patformChannelMapper.cleanChannelForGB(parentPlatform.getServerGBId());
 		return result > 0;
 	}
 
@@ -329,4 +329,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
 
 		return result;
 	}
+
+	@Override
+	public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) {
+		DeviceChannel channel = patformChannelMapper.queryChannelInParentPlatform(platformId, channelId);
+		return channel;
+	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
index 031fb09fa..ca116d53a 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
@@ -110,7 +110,7 @@ public class PlatformController {
         if (logger.isDebugEnabled()) {
             logger.debug("查询所有上级设备API调用");
         }
-        if (StringUtils.isEmpty(parentPlatform.getDeviceGBId())
+        if (StringUtils.isEmpty(parentPlatform.getServerGBId())
         ){
             return new ResponseEntity<>("missing parameters", HttpStatus.BAD_REQUEST);
         }
@@ -118,14 +118,14 @@ public class PlatformController {
         // 发送离线消息,无论是否成功都删除缓存
         commanderForPlatform.unregister(parentPlatform, (event -> {
             // 清空redis缓存
-            redisCatchStorage.delPlatformCatchInfo(parentPlatform.getDeviceGBId());
-            redisCatchStorage.delPlatformKeepalive(parentPlatform.getDeviceGBId());
-            redisCatchStorage.delPlatformRegister(parentPlatform.getDeviceGBId());
+            redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
+            redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
+            redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
         }), (event -> {
             // 清空redis缓存
-            redisCatchStorage.delPlatformCatchInfo(parentPlatform.getDeviceGBId());
-            redisCatchStorage.delPlatformKeepalive(parentPlatform.getDeviceGBId());
-            redisCatchStorage.delPlatformRegister(parentPlatform.getDeviceGBId());
+            redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
+            redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
+            redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
         }));
 
         boolean deleteResult = storager.deleteParentPlatform(parentPlatform);