Browse Source

Merge remote-tracking branch 'origin/master'

jslee(madeinlab) 3 years ago
parent
commit
57658bcbd2
50 changed files with 14163 additions and 676 deletions
  1. 1 1
      WallPadCall/build.gradle
  2. 105 0
      WallPadCall/src/main/java/bssoft/stack/sip/BSSVideo.java
  3. 3855 0
      WallPadCall/src/main/java/bssoft/stack/sip/CMCore.java
  4. 21 0
      WallPadCall/src/main/java/bssoft/stack/sip/Frequent.java
  5. 36 0
      WallPadCall/src/main/java/bssoft/stack/sip/GetIpDns.java
  6. 82 0
      WallPadCall/src/main/java/bssoft/stack/sip/History.java
  7. 95 0
      WallPadCall/src/main/java/bssoft/stack/sip/RFC2833.java
  8. 328 0
      WallPadCall/src/main/java/bssoft/stack/sip/RTPCore.java
  9. 316 0
      WallPadCall/src/main/java/bssoft/stack/sip/SDPMedia.java
  10. 138 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPAUTHENTICATEHeader.java
  11. 330 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPCONTACTHeader.java
  12. 2511 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPCall.java
  13. 362 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPG711.java
  14. 225 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPHeader.java
  15. 268 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPHeaderParty.java
  16. 135 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPROUTEHeader.java
  17. 204 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPRequestLine.java
  18. 248 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPSdp.java
  19. 785 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPStack.java
  20. 124 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPVIAHeader.java
  21. 38 0
      WallPadCall/src/main/java/bssoft/stack/sip/SIPmd5.java
  22. 294 0
      WallPadCall/src/main/java/bssoft/stack/sip/UPDATEHeaders.java
  23. 11 0
      WallPadCall/src/main/java/bssoft/stack/sip/UserDial.java
  24. 87 0
      WallPadCall/src/main/java/bssoft/stack/sip/stackKey.java
  25. 228 0
      WallPadCall/src/main/java/bssoft/stack/sip/videoEnc.java
  26. 47 5
      WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/CallController.java
  27. 24 2
      WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/CallManager.java
  28. 8 8
      WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/SIPInterface.java
  29. 8 1
      WallPadCall/src/main/java/kr/co/icontrols/callengine/sip/SIPSound.java
  30. 23 9
      WallPadCall/src/main/java/kr/co/icontrols/callengine/sip/SIPStun.java
  31. 1 2
      WallPadCall/src/main/java/kr/co/icontrols/callengine/subphone/SubPhoneSerialManager.java
  32. 115 14
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/MainActivity.java
  33. 162 5
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/declare/DataClasses.java
  34. 7 1
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/declare/Global.java
  35. 153 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_delete.java
  36. 153 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_inquiry.java
  37. 153 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_save.java
  38. 146 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_lobby_capture.java
  39. 131 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_start_talking.java
  40. 129 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_stop_talking.java
  41. 153 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_visitor_picture_delete.java
  42. 152 0
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_visitor_picture_inquiry.java
  43. 238 52
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/InquiryCallHistory.java
  44. 368 61
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/InquiryVisitorPictureHistory.java
  45. 324 374
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkFront.java
  46. 164 8
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkLobby.java
  47. 435 117
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkResidence.java
  48. 148 15
      WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/VisitorPictureViewer.java
  49. 3 1
      WallPadMain/src/main/java/kr/co/icontrols/wallpadmain/MainActivity.java
  50. 91 0
      WallPadMain/src/main/java/kr/co/icontrols/wallpadmain/util/iMapServer.java

+ 1 - 1
WallPadCall/build.gradle

@@ -78,7 +78,7 @@ android {
 
 dependencies {
     implementation 'androidx.legacy:legacy-support-v4:1.0.0'
-    implementation files('libs/bssofthns.jar')
+    //implementation files('libs/bssofthns.jar')
     implementation files('libs/WallPadAPI.jar')
     implementation files('libs/WallPadSupport.jar')
     implementation files('libs/visitorcalllib-debug.aar')

+ 105 - 0
WallPadCall/src/main/java/bssoft/stack/sip/BSSVideo.java

@@ -0,0 +1,105 @@
+package bssoft.stack.sip;
+
+import java.util.Date;
+
+public class BSSVideo {
+    public static int HNS_SERVICE_NONE = 9;
+
+    public static int HNS_SERVICE_DOOR = 0;
+
+    public static int HNS_SERVICE_LOBBY = 1;
+
+    public static int HNS_SERVICE_GUARD = 2;
+
+    public static int HNS_SERVICE_NEIGHBOR = 3;
+
+    public static int HNS_SERVICE_TELEPHONE = 4;
+
+    public static int HNS_SERVICE_HISTORY = 5;
+
+    public static int HNS_SERVICE_PICTURE = 6;
+
+    public static int HNS_SERVICE_ORIGINATOR_SELECTED = HNS_SERVICE_NEIGHBOR;
+
+    public static int HNS_SERVICE_RECEIVER_SELECTED = HNS_SERVICE_NONE;
+
+    public static String HNS_PREFIX_LOBBY = "HNSLOBBY.";
+
+    public static String HNS_PREFIX_GUARD = "HNSGUARD.";
+
+    public static String HNS_PREFIX_NEIGHBOR = "HNSNEIGHBOR.";
+
+    public static String HNS_POSTFIX_LOBBY = ".HNSLOBBY";
+
+    public static String HNS_POSTFIX_GUARD = ".HNSGUARD";
+
+    public static String HNS_POSTFIX_NEIGHBOR = ".HNSNEIGHBOR";
+
+    public static int codec = 98;
+
+    public static int VIDEO_PTIME = 200;
+
+    public static boolean bInitializeMode = false;
+
+    public static int camera_width = 320;
+
+    public static int camera_height = 240;
+
+    public static int decode_width = 320;
+
+    public static int decode_height = 240;
+
+    public static int yuv_width = 320;
+
+    public static int yuv_height = 240;
+
+    public static int yuv_offset_x = 0;
+
+    public static int yuv_offset_y = 0;
+
+    public static int ENCODE_FRAME_RATE = 30;
+
+    public static int KEY_FRAME_RATE = 15;
+
+    public static int KEY_I_FRAME_INTERVAL = 5;
+
+    public static int KEY_BIT_RATE = 1440000;
+
+    public static boolean bService = false;
+
+    public static boolean bViewme = false;
+
+    public static int displaySizeType = 0;
+
+    public static boolean bSending = false;
+
+    public static boolean bFrameSet = false;
+
+    public static int iFrames = 0;
+
+    public static String remoteIp = null;
+
+    public static int remotePort = 3002;
+
+    public static int iRunmode = 0;
+
+    public static boolean bVideoEncoding = false;
+
+    public static boolean bVideoDecoding = false;
+
+    public static boolean bSurfaceoutput = true;
+
+    public static boolean bCover = true;
+
+    public static boolean bRemoteview = false;
+
+    public static Date dateVideoincoming = new Date();
+
+    public static int incurtenLength = 2000;
+
+    public static int outcurtenLength = 1000;
+
+    public static boolean bVideoMute = false;
+
+    public static boolean bProgressvideooffer = false;
+}

+ 3855 - 0
WallPadCall/src/main/java/bssoft/stack/sip/CMCore.java

@@ -0,0 +1,3855 @@
+package bssoft.stack.sip;
+
+import android.util.Log;
+
+import java.util.Date;
+import java.util.StringTokenizer;
+import java.util.Timer;
+
+public class CMCore {
+    String TAG = "CMCore";
+
+    public String commandLine = null;
+
+    public String viaH = null;
+
+    public String maxforwardH = null;
+
+    public String contactH = null;
+
+    public String toH = null;
+
+    public String fromH = null;
+
+    public String callidH = null;
+
+    public String cseqH = null;
+
+    public String expiresH = null;
+
+    public String allowH = null;
+
+    public String useragentH = null;
+
+    public String contentlengthH = null;
+
+    public String authorizationH = null;
+
+    public String serverIp = null;
+
+    public int serverPort = 5060;
+
+    public String serverDomain = null;
+
+    public String id = null;
+
+    public String cid = null;
+
+    public String authid = null;
+
+    public String authpassword = null;
+
+    public String localIp = null;
+
+    public String fromTag = null;
+
+    public String callId = null;
+
+    public int localPort = 5060;
+
+    public byte[] byteAddress = null;
+
+    public int CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_REGISTER;
+
+    public int regState = SIPStack.SIP_REGSTATE_IDLE;
+
+    public Date regTime = new Date();
+
+    public Date callTime = new Date();
+
+    public int expiresSeconds = 60;
+
+    public int repeatRegisterCount = 0;
+
+    public int registerNonceCount = 0;
+
+    public String ifIp = null;
+
+    public int ifPort = 5060;
+
+    public String previfIp = null;
+
+    public int previfPort = 5060;
+
+    public boolean bInterfaceChanged = false;
+
+    public String message = null;
+
+    public int serviceMode = SIPStack.SIP_SERVICEMODE_BASIC;
+
+    public boolean bRequestReadySet = false;
+
+    public Timer SIGNALCTRLTimer = null;
+
+    public Thread SIGNALCTRLThread = null;
+
+    public boolean SIGNALCTRLRunning = false;
+
+    public int ctrlIndex = 0;
+
+    public Date ctrlIntervalTimer = new Date();
+
+    public Date netcheckIntervalTimer = new Date();
+
+    public Date registStatusTimer = new Date();
+
+    public static Date pauseTime = new Date();
+
+    public static boolean bPausing = true;
+
+    public static final int BSSSIPStun_ICONTROLS_REGISTER = 1;
+
+    public static final int BSSSIPStun_ICONTROLS_UNREGISTER = 2;
+
+    public static final int BSSSIPStun_ICONTROLS_SET_INT_VALUE = 3;
+
+    public static final int BSSSIPStun_ICONTROLS_SET_STRING_VALUE = 4;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_UPDATESTATUS_TRUE = 10;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_UPDATESTATUS_FALSE = 11;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_VIDEOSET_TRUE = 12;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_VIDEOSET_FALSE = 13;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_INCOMINGCALL = 14;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLCONNECTED = 15;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_SHUTDOWNAPPLICATION = 16;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_BACKGROUNDINCOMINGCALL = 17;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_VIBRATOR_TRUE = 18;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_VIBRATOR_FALSE = 19;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_REGISTSTATUS_TRUE = 20;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_REGISTSTATUS_FALSE = 21;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_RINGBACKTONE_TRUE = 22;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_RINGBACKTONE_FALSE = 23;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLEND_TRUE = 24;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLEND_FALSE = 25;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_OUTBANDDTMF = 26;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_PADNUMBER = 27;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_PADTYPE = 28;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLNEIGHBOR = 29;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLGUARD = 30;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CALLTIME = 31;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_INCOMINGMULTICALL = 32;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_ENDMULTICALL = 33;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_NORMALIZEMULTICALL = 34;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_CANCELMULTICALL = 35;
+
+    public static final int BSSSIPStun_ICONTROLS_CM_OUTCALLFAIL = 36;
+
+    public static final int BSSSIPStun_ICONTROLS_DIALER_ACCEPTMULTICALL = 40;
+
+    public static final int BSSSIPStun_ICONTROLS_DIALER_REJECTMULTICALL = 41;
+
+    public static final int BSSSIPStun_ICONTROLS_DIALER_CANCELMULTICALL = 42;
+
+    public static final int BSSSIPStun_ICONTROLS_DIALER_COMMAND = 43;
+
+    public static final int BSSSIPStun_ICONTROLS_DIALER_FORWARD = 44;
+
+    public static final int BSSSIPStun_ICONTROLS_CONTACT_CALLNEIGHBOR = 50;
+
+    public static final int BSSSIPStun_ICONTROLS_CONTACT_CALLGUARD = 51;
+
+    public static final int BSSSIPStun_ICONTROLS_BLOCK_INVITE_MSG = 100;
+
+    public static final int BSSSIPStun_ICONTROLS_PAUSING_DURATION = 1000;
+
+    public static boolean bDialerActive = false;
+
+    public CMCore() {
+        System.out.println("[CMCore] ========== START ==========");
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        this.commandLine = null;
+        this.viaH = null;
+        this.maxforwardH = null;
+        this.contactH = null;
+        this.toH = null;
+        this.fromH = null;
+        this.callidH = null;
+        this.cseqH = null;
+        this.expiresH = null;
+        this.allowH = null;
+        this.useragentH = null;
+        this.contentlengthH = null;
+        this.authorizationH = null;
+        this.serverIp = null;
+        this.serverPort = 5060;
+        this.serverDomain = null;
+        this.id = null;
+        this.cid = null;
+        this.authid = null;
+        this.authpassword = null;
+        this.localIp = null;
+        this.fromTag = null;
+        this.callId = null;
+        this.localPort = 5060;
+        this.byteAddress = null;
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_REGISTER;
+        this.regState = SIPStack.SIP_REGSTATE_IDLE;
+        this.regTime = new Date();
+        this.callTime = new Date();
+        this.expiresSeconds = 60;
+        this.repeatRegisterCount = 0;
+        this.registerNonceCount = 0;
+        this.ifIp = null;
+        this.ifPort = 5060;
+        this.previfIp = null;
+        this.previfPort = 5060;
+        this.bInterfaceChanged = false;
+        this.message = null;
+        this.serviceMode = SIPStack.SIP_SERVICEMODE_BASIC;
+        this.bRequestReadySet = false;
+        this.SIGNALCTRLTimer = null;
+        this.SIGNALCTRLThread = null;
+        this.SIGNALCTRLRunning = false;
+        this.ctrlIndex = 0;
+        this.ctrlIntervalTimer = new Date();
+        this.netcheckIntervalTimer = new Date();
+        this.registStatusTimer = new Date();
+    }
+
+    public void action_0(byte[] byteLocalip, int localport, byte[] byteServerip, int serverport, byte[] byteServerdomain, byte[] byteId, byte[] byteCid, byte[] byteAuthid, byte[] byteAuthpassword) {
+        this.byteAddress = this.byteAddress;
+        this.localIp = new String(byteLocalip, 0, 0, byteLocalip.length);
+        this.localPort = localport;
+        SIPStack.localSdpIp = new String(byteLocalip, 0, 0, byteLocalip.length);
+        if (SIPStack.usePrivateWiMax && (SIPStack.isInternetWiMax || SIPStack.isInternetMobile) && !SIPStack.isPrivateIp(SIPStack.localSdpIp))
+            SIPStack.localSdpIp = "192.168.10.2";
+        this.ifIp = new String(byteLocalip, 0, 0, byteLocalip.length);
+        this.ifPort = this.localPort;
+        this.serverIp = new String(byteServerip, 0, 0, byteServerip.length);
+        this.serverPort = serverport;
+        this.serverDomain = new String(byteServerdomain, 0, 0, byteServerdomain.length);
+        if (this.serverDomain == null || this.serverDomain.length() == 0)
+            this.serverDomain = new String(this.serverIp);
+        this.id = new String(byteId, 0, 0, byteId.length);
+        this.cid = new String(byteCid, 0, 0, byteCid.length);
+        if (this.cid.length() < 7 || this.cid.length() == 0)
+            this.cid = new String(this.id);
+        this.authid = new String(byteAuthid, 0, 0, byteAuthid.length);
+        this.authpassword = new String(byteAuthpassword, 0, 0, byteAuthpassword.length);
+        this.commandLine = "REGISTER sip:" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        Date today = new Date();
+        this.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+        this.maxforwardH = "Max-Forwards: 70";
+        this.contactH = "Contact: <sip:" + this.id + "@" + this.localIp + ":" + this.localPort + ">";
+        this.toH = "To: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">";
+        this.fromTag = SIPStack.newTag();
+        this.fromH = "From: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">;tag=" + this.fromTag;
+        this.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+        this.callidH = "Call-ID: " + this.callId;
+        if (this.CSEQ_NUMBER > 65556)
+            this.CSEQ_NUMBER = 0;
+        SIPStack.SIP_SEQUENCE_REGISTER = this.CSEQ_NUMBER;
+        this.cseqH = "CSeq: " + this.CSEQ_NUMBER + " REGISTER";
+        this.expiresH = "Expires: " + this.expiresSeconds;
+        this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+        this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+        this.contentlengthH = "Content-Length: 0";
+        this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                this.viaH + SIPStack.SIP_LINE_END +
+                this.maxforwardH + SIPStack.SIP_LINE_END +
+                this.contactH + SIPStack.SIP_LINE_END +
+                this.fromH + SIPStack.SIP_LINE_END +
+                this.toH + SIPStack.SIP_LINE_END +
+                this.callidH + SIPStack.SIP_LINE_END +
+                this.cseqH + SIPStack.SIP_LINE_END +
+                this.expiresH + SIPStack.SIP_LINE_END +
+                this.allowH + SIPStack.SIP_LINE_END +
+                this.useragentH + SIPStack.SIP_LINE_END +
+                this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        if (SIPStack.bUseCtrlTimer) {
+            if (this.SIGNALCTRLTimer != null)
+                this.SIGNALCTRLTimer.cancel();
+        } else {
+            if (this.SIGNALCTRLThread != null)
+                this.SIGNALCTRLThread.interrupt();
+            this.SIGNALCTRLRunning = false;
+        }
+        this.SIGNALCTRLTimer = new Timer();
+    }
+
+    public void action_1(byte[] byteAddress, byte[] byteLocalip, int localport, String strServerHost, int serverport, String strServerDomain, byte[] byteId, byte[] byteCid, byte[] byteAuthid, byte[] byteAuthpassword) {
+        byteAddress = byteAddress;
+        this.localIp = new String(byteLocalip, 0, 0, byteLocalip.length);
+        this.localPort = localport;
+        SIPStack.localSdpIp = this.localIp;
+        this.ifIp = new String(byteLocalip, 0, 0, byteLocalip.length);
+        this.ifPort = this.localPort;
+        this.serverPort = serverport;
+        SIPStack.ipdns.bSipAddressResolved = false;
+        SIPStack.ipdns.sipServerHost = "";
+        this.serverDomain = "";
+        this.serverIp = "";
+        SIPStack.ipdns.sipTry = 0;
+        if (strServerDomain != null && strServerDomain.length() > 0)
+            this.serverDomain = new String(strServerDomain);
+        if (strServerHost != null && strServerHost.length() > 0) {
+            SIPStack.ipdns.sipServerHost = strServerHost;
+        } else {
+            SIPStack.ipdns.bSipAddressResolved = true;
+        }
+        this.id = new String(byteId, 0, 0, byteId.length);
+        this.cid = new String(byteCid, 0, 0, byteCid.length);
+        if (this.cid.length() < 7 || this.cid.length() == 0)
+            this.cid = new String(this.id);
+        this.authid = new String(byteAuthid, 0, 0, byteAuthid.length);
+        this.authpassword = new String(byteAuthpassword, 0, 0, byteAuthpassword.length);
+        this.commandLine = "REGISTER sip:" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        Date today = new Date();
+        this.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+        this.maxforwardH = "Max-Forwards: 70";
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            this.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            this.contactH = "Contact: <sip:" + this.id + "@" + this.localIp + ":" + this.localPort + ">";
+        }
+        this.toH = "To: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">";
+        this.fromTag = SIPStack.newTag();
+        this.fromH = "From: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">;tag=" + this.fromTag;
+        this.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+        this.callidH = "Call-ID: " + this.callId;
+        if (this.CSEQ_NUMBER > 65556)
+            this.CSEQ_NUMBER = 0;
+        SIPStack.SIP_SEQUENCE_REGISTER = this.CSEQ_NUMBER;
+        this.cseqH = "CSeq: " + this.CSEQ_NUMBER + " REGISTER";
+        this.expiresH = "Expires: " + this.expiresSeconds;
+        this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+        this.useragentH = "User-Agent: " + SIPStack.USER_AGENT;
+        this.contentlengthH = "Content-Length: 0";
+        this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                this.viaH + SIPStack.SIP_LINE_END +
+                this.maxforwardH + SIPStack.SIP_LINE_END +
+                this.contactH + SIPStack.SIP_LINE_END +
+                this.fromH + SIPStack.SIP_LINE_END +
+                this.toH + SIPStack.SIP_LINE_END +
+                this.callidH + SIPStack.SIP_LINE_END +
+                this.cseqH + SIPStack.SIP_LINE_END +
+                this.expiresH + SIPStack.SIP_LINE_END +
+                this.allowH + SIPStack.SIP_LINE_END +
+                this.useragentH + SIPStack.SIP_LINE_END +
+                this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        if (SIPStack.bUseCtrlTimer) {
+            if (this.SIGNALCTRLTimer != null)
+                this.SIGNALCTRLTimer.cancel();
+        } else {
+            if (this.SIGNALCTRLThread != null)
+                this.SIGNALCTRLThread.interrupt();
+            this.SIGNALCTRLRunning = false;
+        }
+        this.SIGNALCTRLTimer = new Timer();
+    }
+
+    public void action_2(String strId, String strCid, String strAuthid, String strAuthpassword, String strServerHost, String strServerDomain, int serverport) {
+        this.serverIp = SIPStack.getIPV4(strServerHost);
+        if (this.serverIp == null)
+            this.serverIp = "";
+        if (strServerDomain == null || strServerDomain.length() == 0) {
+            this.serverDomain = new String(this.serverIp);
+        } else {
+            this.serverDomain = new String(strServerDomain);
+        }
+        this.serverPort = serverport;
+        this.id = new String(strId);
+        this.cid = new String(strCid);
+        this.authid = new String(strAuthid);
+        this.authpassword = new String(strAuthpassword);
+        this.regState = SIPStack.SIP_REGSTATE_REGISTERING;
+    }
+
+    public boolean action_net_0() {
+        try {
+            if (!SIPStack.ipdns.bSipAddressResolved &&
+                    SIPStack.ipdns.sipServerHost != null &&
+                    SIPStack.ipdns.sipServerHost.length() > 0) {
+                this.serverIp = SIPStack.getIPV4(SIPStack.ipdns.sipServerHost);
+                SIPStack.ipdns.sipTry++;
+                if (this.serverIp == null) {
+                    this.serverIp = "";
+                } else {
+                    SIPStack.ipdns.bSipAddressResolved = true;
+                }
+                if (this.serverDomain == null || this.serverDomain.length() == 0)
+                    this.serverDomain = new String(SIPStack.ipdns.sipServerHost);
+                if (this.serverIp != null && this.serverIp.length() > 0) {
+                    this.regState = SIPStack.SIP_REGSTATE_REGISTERING;
+                    return true;
+                }
+            }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public void action_net_1(String host) {
+        try {
+            if (host != null && host.length() > 0) {
+                String ip = SIPStack.getIPV4(host);
+                if (ip != null && ip.length() > 0)
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_AVAILABLE;
+                if (ip != null && ip.length() > 0 && ip.compareToIgnoreCase(this.localIp) != 0) {
+                    this.localIp = new String(ip);
+                    if (SIPStack.usePrivateWiMax && (
+                            SIPStack.isInternetWiMax || SIPStack.isInternetMobile) &&
+                            !SIPStack.isPrivateIp(ip)) {
+                        SIPStack.localSdpIp = "192.168.10.2";
+                    } else {
+                        SIPStack.localSdpIp = new String(ip);
+                    }
+                    if (this.ifIp == null || this.ifIp.length() == 0 || this.ifPort <= 0) {
+                        this.ifIp = new String(this.localIp);
+                        this.ifPort = SIPStack.SIP_LOCAL_PORT;
+                    }
+                } else if (ip == null || ip.length() == 0) {
+                    this.localIp = "127.0.0.1";
+                    SIPStack.localSdpIp = "127.0.0.1";
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+                }
+            } else if (host == null || host.length() == 0) {
+                this.localIp = "127.0.0.1";
+                SIPStack.localSdpIp = "127.0.0.1";
+                SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+            }
+        } catch (Exception exception) {}
+    }
+
+    public boolean action_net_2(String host) {
+        try {
+            if (host != null && host.length() > 0) {
+                String ip = SIPStack.getIPV4(host);
+                if (ip != null && ip.length() > 0)
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_AVAILABLE;
+                if (ip != null && ip.length() > 0 && ip.compareToIgnoreCase(this.localIp) != 0) {
+                    this.localIp = new String(ip);
+                    if (SIPStack.usePrivateWiMax && (
+                            SIPStack.isInternetWiMax || SIPStack.isInternetMobile) &&
+                            !SIPStack.isPrivateIp(ip)) {
+                        SIPStack.localSdpIp = "192.168.10.2";
+                    } else {
+                        SIPStack.localSdpIp = new String(ip);
+                    }
+                    this.ifIp = new String(this.localIp);
+                    this.ifPort = SIPStack.SIP_LOCAL_PORT;
+                    this.authorizationH = "";
+                    return true;
+                }
+                if (ip == null || ip.length() == 0) {
+                    this.localIp = "127.0.0.1";
+                    SIPStack.localSdpIp = "127.0.0.1";
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+                }
+            } else if (host == null || host.length() == 0) {
+                this.localIp = "127.0.0.1";
+                SIPStack.localSdpIp = "127.0.0.1";
+                SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+            }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean action_net_3(String host) {
+        try {
+            if (host != null && host.length() > 0) {
+                String ip = SIPStack.getIPV4(host);
+                if (ip != null && ip.length() > 0)
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_AVAILABLE;
+                if (ip != null && ip.length() > 0 && ip.compareToIgnoreCase(this.localIp) != 0) {
+                    this.localIp = new String(ip);
+                    if (SIPStack.usePrivateWiMax && (
+                            SIPStack.isInternetWiMax || SIPStack.isInternetMobile) &&
+                            !SIPStack.isPrivateIp(ip)) {
+                        SIPStack.localSdpIp = "192.168.10.2";
+                    } else {
+                        SIPStack.localSdpIp = new String(ip);
+                    }
+                    this.bInterfaceChanged = true;
+                    this.previfIp = this.ifIp;
+                    this.previfPort = this.ifPort;
+                    this.ifIp = new String(this.localIp);
+                    this.ifPort = SIPStack.SIP_LOCAL_PORT;
+                    return true;
+                }
+                if (ip == null || ip.length() == 0) {
+                    this.localIp = "127.0.0.1";
+                    SIPStack.localSdpIp = "127.0.0.1";
+                    SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+                }
+            } else if (host == null || host.length() == 0) {
+                this.localIp = "127.0.0.1";
+                SIPStack.localSdpIp = "127.0.0.1";
+                SIPStack.networkStatus = SIPStack.SIP_NETIF_UNAVAILABLE;
+            }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public SIPCONTACTHeader action_reg_0(String message) {
+        try {
+            String requestUri = "sip:" + this.id + "@" + this.localIp + ":" + this.localPort;
+            if (this.ifIp != null &&
+                    this.ifIp.length() > 0 &&
+                    this.ifPort > 0)
+                if (this.bInterfaceChanged) {
+                    requestUri = "sip:" + this.id + "@" + this.previfIp + ":" + this.previfPort;
+                } else {
+                    requestUri = "sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort;
+                }
+            return new SIPCONTACTHeader(message, requestUri);
+        } catch (Exception exception) {
+            return null;
+        }
+    }
+
+    public boolean action_reg_1(String message) {
+        try {
+            SIPVIAHeader viaHeader = new SIPVIAHeader(message);
+            if (viaHeader.flag && viaHeader.rportService &&
+                    viaHeader.rport > 0 && viaHeader.received.length() > 0)
+                if (this.ifIp == null ||
+                        this.ifIp.length() == 0 ||
+                        this.ifPort <= 0 ||
+                        this.ifIp.compareToIgnoreCase(viaHeader.received) != 0 ||
+                        this.ifPort != viaHeader.rport) {
+                    this.bInterfaceChanged = true;
+                    this.previfIp = this.ifIp;
+                    this.previfPort = this.ifPort;
+                    this.ifIp = new String(viaHeader.received);
+                    this.ifPort = viaHeader.getRport();
+                    return true;
+                }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean action_reg_2(String message) {
+        try {
+            this.authorizationH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE);
+            if (sipHeader == null || !sipHeader.flag)
+                sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE);
+            if (sipHeader != null && sipHeader.flag) {
+                SIPAUTHENTICATEHeader authHeader =
+                        new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE);
+                if (authHeader == null || !authHeader.flag)
+                    authHeader = new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE);
+                if (authHeader != null && authHeader.flag)
+                    if (authHeader.nonceValue.length() > 0 && authHeader.realmValue.length() > 0) {
+                        String qop = authHeader.qopValue;
+                        String uri = "sip:" + this.serverDomain + ":" + this.serverPort;
+                        this.authorizationH = getAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_REGISTER);
+                        return true;
+                    }
+            }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean action_reg_3(String message) {
+        try {
+            this.regState = SIPStack.SIP_REGSTATE_UNAUTHORIZED;
+            this.authorizationH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE);
+            if (sipHeader != null && sipHeader.flag) {
+                SIPAUTHENTICATEHeader authHeader =
+                        new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE);
+                if (authHeader != null && authHeader.flag)
+                    if (authHeader.nonceValue.length() > 0 && authHeader.realmValue.length() > 0) {
+                        String qop = authHeader.qopValue;
+                        String uri = "sip:" + this.serverDomain + ":" + this.serverPort;
+                        this.authorizationH = getProxyAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_REGISTER);
+                        return true;
+                    }
+            }
+            return false;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public void action_reg_4(String message) {
+        try {
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_MINEXPIRES);
+            if (sipHeader != null && sipHeader.flag)
+                this.expiresSeconds = Integer.parseInt(sipHeader.headerValue);
+            this.regState = SIPStack.SIP_REGSTATE_IDLE;
+        } catch (Exception exception) {}
+    }
+
+    public boolean action_bye_0(SIPCall sipCall, String message) {
+        try {
+            SIPRequestLine requestLine = new SIPRequestLine(message);
+            if (requestLine != null) {
+                SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                boolean bValidCall = false;
+                if (sipHeader != null && sipHeader.flag)
+                    if (sipHeader.headerValue != null &&
+                            sipHeader.headerValue.length() > 0 &&
+                            sipCall.callId != null &&
+                            sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                        bValidCall = true;
+                if (bValidCall) {
+                    sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                    if (sipHeader != null && sipHeader.flag) {
+                        int duration = 0;
+                        Date currentTime = new Date();
+                        if (sipCall.callTime_T4 != null)
+                            duration = (int)(currentTime.getTime() - sipCall.callTime_T4.getTime()) / 1000;
+                        sipCall.BYE_CSEQ = sipHeader.callSequenceNumber();
+                        sipCall.callState = 9;
+                        sipCall.callTime_T6 = new Date();
+                        return true;
+                    }
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean action_bye_1(SIPCall sipCall, String message) {
+        try {
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            boolean bValidCall = false;
+            if (sipHeader != null && sipHeader.flag)
+                if (sipHeader.headerValue != null &&
+                        sipHeader.headerValue.length() > 0 &&
+                        sipCall.callId != null &&
+                        sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                    bValidCall = true;
+            if (bValidCall) {
+                sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                if (sipHeader != null && sipHeader.flag) {
+                    sipCall.BYE_CSEQ = sipHeader.callSequenceNumber();
+                    sipCall.bByedisconnected = false;
+                    sipCall.resetCall();
+                    return true;
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean action_info_0(SIPCall sipCall, String message, int msgType) {
+        try {
+            if (msgType == SIPStack.SIP_MSGTYPE_REQUEST &&
+                    sipCall.flag &&
+                    sipCall.callState == 7) {
+                SIPRequestLine requestLine = new SIPRequestLine(message);
+                if (requestLine != null) {
+                    SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                    if (sipHeader != null && sipHeader.flag)
+                        if (sipHeader.headerValue != null &&
+                                sipHeader.headerValue.length() > 0 &&
+                                sipCall.callId != null &&
+                                sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                            return true;
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public String getAuthorizationHeader(String qop, String authid, String realmValue, String authpassword, String uri, String nonceValue, int methodType) {
+        String strHeader = null;
+        String finalDigest = null;
+        String step1Digest = SIPStack.BSSMD5Get(String.valueOf(authid) + ":" + realmValue + ":" + authpassword);
+        String step2Digest = null;
+        if (methodType == SIPStack.SIP_METHODTYPE_REGISTER) {
+            step2Digest = SIPStack.BSSMD5Get("REGISTER:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_INVITE) {
+            step2Digest = SIPStack.BSSMD5Get("INVITE:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_CANCEL) {
+            step2Digest = SIPStack.BSSMD5Get("CANCEL:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_ACK) {
+            step2Digest = SIPStack.BSSMD5Get("ACK:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_BYE) {
+            step2Digest = SIPStack.BSSMD5Get("BYE:" + uri);
+        }
+        this.registerNonceCount++;
+        if (qop.length() > 0) {
+            int nonceCount = 0;
+            String cnonce = SIPStack.BSSMD5Get("60cf184b29500b20" + this.registerNonceCount);
+            if (nonceValue.length() > 0)
+                nonceCount = 1;
+            finalDigest = SIPStack.BSSMD5Get(String.valueOf(step1Digest) + ":" + nonceValue + ":" + String.format("%08x", new Object[] { Integer.valueOf(nonceCount) }) + ":" + cnonce + ":" + qop + ":" + step2Digest);
+            strHeader = "Authorization: Digest username=\"" +
+                    authid + "\"," +
+                    " realm=\"" + realmValue + "\"," +
+                    " nonce=\"" + nonceValue + "\"," +
+                    " uri=\"" + uri + "\"," +
+                    " response=\"" + finalDigest + "\"," +
+                    " cnonce=\"" + cnonce + "\"," +
+                    " nc=" + String.format("%08x", new Object[] { Integer.valueOf(nonceCount) }) + "," +
+                    " qop=" + qop + "," +
+                    " algorithm=MD5";
+        } else {
+            finalDigest = SIPStack.BSSMD5Get(String.valueOf(step1Digest) + ":" + nonceValue + ":" + step2Digest);
+            strHeader = "Authorization: Digest username=\"" +
+                    authid + "\"," +
+                    " realm=\"" + realmValue + "\"," +
+                    " nonce=\"" + nonceValue + "\"," +
+                    " uri=\"" + uri + "\"," +
+                    " response=\"" + finalDigest + "\"," +
+                    " algorithm=MD5";
+        }
+        return strHeader;
+    }
+
+    public String getProxyAuthorizationHeader(String qop, String authid, String realmValue, String authpassword, String uri, String nonceValue, int methodType) {
+        String strHeader = null;
+        String finalDigest = null;
+        String step1Digest = SIPStack.BSSMD5Get(String.valueOf(authid) + ":" + realmValue + ":" + authpassword);
+        String step2Digest = null;
+        if (methodType == SIPStack.SIP_METHODTYPE_REGISTER) {
+            step2Digest = SIPStack.BSSMD5Get("REGISTER:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_INVITE) {
+            step2Digest = SIPStack.BSSMD5Get("INVITE:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_CANCEL) {
+            step2Digest = SIPStack.BSSMD5Get("CANCEL:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_ACK) {
+            step2Digest = SIPStack.BSSMD5Get("ACK:" + uri);
+        } else if (methodType == SIPStack.SIP_METHODTYPE_BYE) {
+            step2Digest = SIPStack.BSSMD5Get("BYE:" + uri);
+        }
+        this.registerNonceCount++;
+        if (qop.length() > 0) {
+            int nonceCount = 0;
+            String cnonce = SIPStack.BSSMD5Get("60cf184b29500b20" + this.registerNonceCount);
+            if (nonceValue.length() > 0)
+                nonceCount = 1;
+            finalDigest = SIPStack.BSSMD5Get(String.valueOf(step1Digest) + ":" + nonceValue + ":" + String.format("%08x", new Object[] { Integer.valueOf(nonceCount) }) + ":" + cnonce + ":" + qop + ":" + step2Digest);
+            strHeader = "Proxy-Authorization: Digest username=\"" +
+                    authid + "\"," +
+                    " realm=\"" + realmValue + "\"," +
+                    " nonce=\"" + nonceValue + "\"," +
+                    " uri=\"" + uri + "\"," +
+                    " response=\"" + finalDigest + "\"," +
+                    " cnonce=\"" + cnonce + "\"," +
+                    " nc=" + String.format("%08x", new Object[] { Integer.valueOf(nonceCount) }) + "," +
+                    " qop=" + qop + "," +
+                    " algorithm=MD5";
+        } else {
+            finalDigest = SIPStack.BSSMD5Get(String.valueOf(step1Digest) + ":" + nonceValue + ":" + step2Digest);
+            strHeader = "Proxy-Authorization: Digest username=\"" +
+                    authid + "\"," +
+                    " realm=\"" + realmValue + "\"," +
+                    " nonce=\"" + nonceValue + "\"," +
+                    " uri=\"" + uri + "\"," +
+                    " response=\"" + finalDigest + "\"," +
+                    " algorithm=MD5";
+        }
+        return strHeader;
+    }
+
+    public boolean makeRegister() {
+        try {
+            this.CSEQ_NUMBER++;
+            this.commandLine = "REGISTER sip:" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            Date today = new Date();
+            this.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+            this.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                this.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                this.contactH = "Contact: <sip:" + this.id + "@" + this.localIp + ":" + this.localPort + ">";
+            }
+            this.toH = "To: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">";
+            this.fromTag = SIPStack.newTag();
+            this.fromH = "From: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">;tag=" + this.fromTag;
+            if (this.callId == null || this.callId.length() == 0) {
+                this.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+                this.callidH = "Call-ID: " + this.callId;
+            }
+            if (this.CSEQ_NUMBER > 65556)
+                this.CSEQ_NUMBER = 0;
+            SIPStack.SIP_SEQUENCE_REGISTER = this.CSEQ_NUMBER;
+            this.cseqH = "CSeq: " + this.CSEQ_NUMBER + " REGISTER";
+            this.expiresH = "Expires: " + this.expiresSeconds;
+            this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            this.contentlengthH = "Content-Length: 0";
+            if (this.authorizationH != null && this.authorizationH.length() > 0) {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.authorizationH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeUNRegister() {
+        try {
+            this.CSEQ_NUMBER++;
+            this.commandLine = "REGISTER sip:" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            Date today = new Date();
+            this.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+            this.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                this.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">;expires=0";
+            } else {
+                this.contactH = "Contact: <sip:" + this.id + "@" + this.localIp + ":" + this.localPort + ">;expires=0";
+            }
+            this.toH = "To: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">";
+            this.fromTag = SIPStack.newTag();
+            this.fromH = "From: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">;tag=" + this.fromTag;
+            if (this.callId == null || this.callId.length() == 0) {
+                this.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+                this.callidH = "Call-ID: " + this.callId;
+            }
+            if (this.CSEQ_NUMBER > 65556)
+                this.CSEQ_NUMBER = 0;
+            SIPStack.SIP_SEQUENCE_REGISTER = this.CSEQ_NUMBER;
+            this.cseqH = "CSeq: " + this.CSEQ_NUMBER + " REGISTER";
+            this.expiresH = "Expires: 0";
+            this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            this.contentlengthH = "Content-Length: 0";
+            if (this.authorizationH != null && this.authorizationH.length() > 0) {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.authorizationH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeUNRegister(String contactip, int contactport) {
+        try {
+            this.CSEQ_NUMBER++;
+            this.commandLine = "REGISTER sip:" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            Date today = new Date();
+            this.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+            this.maxforwardH = "Max-Forwards: 70";
+            if (contactip != null && contactip.length() > 0 && contactport > 0) {
+                this.contactH = "Contact: <sip:" + this.id + "@" + contactip + ":" + contactport + ">";
+            } else {
+                return true;
+            }
+            this.toH = "To: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">";
+            this.fromTag = SIPStack.newTag();
+            this.fromH = "From: \"" + this.id + "\"<sip:" + this.id + "@" + this.serverDomain + ":" + this.serverPort + ">;tag=" + this.fromTag;
+            if (this.callId == null || this.callId.length() == 0) {
+                this.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+                this.callidH = "Call-ID: " + this.callId;
+            }
+            if (this.CSEQ_NUMBER > 65556)
+                this.CSEQ_NUMBER = 0;
+            SIPStack.SIP_SEQUENCE_REGISTER = this.CSEQ_NUMBER;
+            this.cseqH = "CSeq: " + this.CSEQ_NUMBER + " REGISTER";
+            this.expiresH = "Expires: 0";
+            this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            this.contentlengthH = "Content-Length: 0";
+            if (this.authorizationH != null && this.authorizationH.length() > 0) {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.authorizationH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                this.message = String.valueOf(this.commandLine) + SIPStack.SIP_LINE_END +
+                        this.viaH + SIPStack.SIP_LINE_END +
+                        this.maxforwardH + SIPStack.SIP_LINE_END +
+                        this.contactH + SIPStack.SIP_LINE_END +
+                        this.fromH + SIPStack.SIP_LINE_END +
+                        this.toH + SIPStack.SIP_LINE_END +
+                        this.callidH + SIPStack.SIP_LINE_END +
+                        this.cseqH + SIPStack.SIP_LINE_END +
+                        this.expiresH + SIPStack.SIP_LINE_END +
+                        this.allowH + SIPStack.SIP_LINE_END +
+                        this.useragentH + SIPStack.SIP_LINE_END +
+                        this.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeCancel(SIPCall sipCall) {
+        if (sipCall == null || !sipCall.flag)
+            return false;
+        sipCall.CANCEL_CSEQ = sipCall.CSEQ_NUMBER;
+        if (sipCall.callState != 1 &&
+                sipCall.callState != 3 &&
+                sipCall.callState != 4)
+            return false;
+        String commandLine = "CANCEL sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        String toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+        if (sipCall.viaH == null || sipCall.viaH.length() == 0) {
+            if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+        }
+        sipCall.cseqH = "CSeq: " + sipCall.CANCEL_CSEQ + " CANCEL";
+        sipCall.contentlengthH = "Content-Length: 0";
+        String routeString = "";
+        if (sipCall.routeArray != null &&
+                sipCall.routeArray.length() > 0)
+            routeString = sipCall.routeArray.toString();
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+        }
+        if (sipCall.authorizationCANCELH != null && sipCall.authorizationCANCELH.length() > 0) {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.authorizationCANCELH + SIPStack.SIP_LINE_END +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        } else {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        }
+        return true;
+    }
+
+    public boolean makeRecancel(SIPCall sipCall) {
+        if (sipCall == null || !sipCall.flag)
+            return false;
+        sipCall.CANCEL_CSEQ = sipCall.CSEQ_NUMBER;
+        if (sipCall.callState != 11)
+            return false;
+        String commandLine = "CANCEL sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        String toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+        if (sipCall.viaH == null || sipCall.viaH.length() == 0) {
+            if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+        }
+        sipCall.cseqH = "CSeq: " + sipCall.CANCEL_CSEQ + " CANCEL";
+        sipCall.contentlengthH = "Content-Length: 0";
+        String routeString = "";
+        if (sipCall.routeArray != null &&
+                sipCall.routeArray.length() > 0)
+            routeString = sipCall.routeArray.toString();
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+        }
+        if (sipCall.authorizationCANCELH != null && sipCall.authorizationCANCELH.length() > 0) {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.authorizationCANCELH + SIPStack.SIP_LINE_END +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        } else {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        }
+        return true;
+    }
+
+    public boolean makeBye(SIPCall sipCall) {
+        if (sipCall == null || !sipCall.flag)
+            return false;
+        if (sipCall.callState != 7 &&
+                sipCall.callState != 5 &&
+                sipCall.callState != 6)
+            return false;
+        String commandLine = null;
+        if (sipCall.remoteContactUri != null && sipCall.remoteContactUri.length() > 0) {
+            commandLine = "BYE " + sipCall.remoteContactUri + " SIP/2.0";
+        } else {
+            commandLine = "BYE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        }
+        if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+            sipCall.viaBranch = SIPStack.getViaBranch();
+        String viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch;
+        String maxforwardH = "Max-Forwards: 70";
+        String contactH = null;
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+        }
+        String toH = null;
+        if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            if (sipCall.fromHeaderValue == null || sipCall.fromHeaderValue.length() == 0) {
+                toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            } else {
+                toH = "To: " + sipCall.fromHeaderValue;
+            }
+        } else {
+            toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.toTag;
+        }
+        String fromH = null;
+        if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            if (sipCall.toHeaderValue == null || sipCall.toHeaderValue.length() == 0) {
+                fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.toTag;
+            } else {
+                fromH = "From: " + sipCall.toHeaderValue;
+            }
+        } else {
+            fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+        }
+        sipCall.BYE_CSEQ = sipCall.CSEQ_NUMBER + 1;
+        String cseqH = "CSeq: " + sipCall.BYE_CSEQ + " BYE";
+        String contentlengthH = "Content-Length: 0";
+        String routeString = "";
+        if (sipCall.routeArray != null &&
+                sipCall.routeArray.length() > 0)
+            routeString = sipCall.routeArray.toString();
+        if (sipCall.authorizationBYEH != null && sipCall.authorizationBYEH.length() > 0) {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            maxforwardH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.authorizationBYEH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        } else {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            maxforwardH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        }
+        return true;
+    }
+
+    public boolean makeReBye(SIPCall sipCall) {
+        if (sipCall == null || !sipCall.flag)
+            return false;
+        if (sipCall.callState != 8 ||
+                !sipCall.bByedisconnected)
+            return false;
+        String commandLine = null;
+        if (sipCall.remoteContactUri != null && sipCall.remoteContactUri.length() > 0) {
+            commandLine = "BYE " + sipCall.remoteContactUri + " SIP/2.0";
+        } else {
+            commandLine = "BYE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+        }
+        if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+            sipCall.viaBranch = SIPStack.getViaBranch();
+        String viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch;
+        String maxforwardH = "Max-Forwards: 70";
+        String contactH = null;
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+        }
+        String toH = null;
+        if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            if (sipCall.fromHeaderValue == null || sipCall.fromHeaderValue.length() == 0) {
+                toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            } else {
+                toH = "To: " + sipCall.fromHeaderValue;
+            }
+        } else {
+            toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.toTag;
+        }
+        String fromH = null;
+        if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            if (sipCall.toHeaderValue == null || sipCall.toHeaderValue.length() == 0) {
+                fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.toTag;
+            } else {
+                fromH = "From: " + sipCall.toHeaderValue;
+            }
+        } else {
+            fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+        }
+        sipCall.BYE_CSEQ = sipCall.CSEQ_NUMBER + 1;
+        String cseqH = "CSeq: " + sipCall.BYE_CSEQ + " BYE";
+        String contentlengthH = "Content-Length: 0";
+        String routeString = "";
+        if (sipCall.routeArray != null &&
+                sipCall.routeArray.length() > 0)
+            routeString = sipCall.routeArray.toString();
+        if (sipCall.authorizationBYEH != null && sipCall.authorizationBYEH.length() > 0) {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            maxforwardH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            sipCall.authorizationBYEH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        } else {
+            sipCall.message =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            viaH + SIPStack.SIP_LINE_END +
+                            routeString +
+                            maxforwardH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+        }
+        return true;
+    }
+
+    public String getVideomediadescription(int port) {
+        String str = "m=video " + port + " RTP/AVP " + SIPStack.SIP_CODEC_H263 + SIPStack.SIP_LINE_END +
+                "a=rtpmap:" + SIPStack.SIP_CODEC_H263 + " H263/90000" + SIPStack.SIP_LINE_END +
+                "a=fmtp:" + SIPStack.SIP_CODEC_H263 + " packetization-mode=1;profile-level-id=2" + SIPStack.SIP_LINE_END +
+                "a=cliprect:0,0,288,352" + SIPStack.SIP_LINE_END +
+                "a=framesize:" + SIPStack.SIP_CODEC_H263 + " 352-288" + SIPStack.SIP_LINE_END;
+        //String str = "";
+        return str;
+    }
+
+    public boolean makeDirectcallMake(SIPCall sipCall, String number) {
+        String header = "";
+        if (sipCall == null || sipCall.flag)
+            return false;
+        sipCall.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        SIPStack.SIP_SEQUENCE_INVITE++;
+        if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+            SIPStack.SIP_SEQUENCE_INVITE = 1;
+        if (!sipCall.activeCallHandle(
+                this.id,
+                this.cid,
+                this.authid,
+                this.authpassword,
+                number,
+                sipCall.serverIp,
+                sipCall.serverPort,
+                sipCall.serverDomain,
+                this.localIp,
+                this.localPort))
+            return false;
+        if (number.length() <= 0)
+            return false;
+        sipCall.commandLine = "INVITE sip:" + number + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + " SIP/2.0";
+        Date today = new Date();
+        sipCall.viaBranch = SIPStack.getViaBranch();
+        sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+        sipCall.maxforwardH = "Max-Forwards: 70";
+        if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+        } else {
+            sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+        }
+        sipCall.toH = "To: \"" + number + "\"<sip:" + number + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+        sipCall.fromTag = SIPStack.newTag();
+        sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+        if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_LOBBY) {
+            String postFix = "";
+            if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+            } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+            } else {
+                postFix = BSSVideo.HNS_POSTFIX_LOBBY;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+            }
+            sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_LOBBY) + SIPStack.BSSMD5Get(this.viaH) +
+                    SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+            sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+            BSSVideo.bProgressvideooffer = true;
+        } else if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+            String postFix = "";
+            if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+            } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+            } else {
+                postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+            }
+            sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_GUARD) + SIPStack.BSSMD5Get(this.viaH) +
+                    SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+            sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_GUARD;
+            BSSVideo.bProgressvideooffer = true;
+        } else if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+            String postFix = "";
+            if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                BSSVideo.bProgressvideooffer = true;
+            } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                BSSVideo.bProgressvideooffer = true;
+            } else {
+                postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+                BSSVideo.bProgressvideooffer = false;
+            }
+            sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_NEIGHBOR) + SIPStack.BSSMD5Get(this.viaH) +
+                    SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+            sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+        } else {
+            sipCall.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+            sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+            sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+            BSSVideo.bProgressvideooffer = false;
+        }
+        sipCall.callidH = "Call-ID: " + sipCall.callId;
+        sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+        sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+        sipCall.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+        if (sipCall.cid != null && sipCall.cid.length() > 0) {
+            sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+        } else {
+            sipCall.passertedidentityH = null;
+            header = "";
+        }
+        int audioport = SIPStack.getFreeAudioRtpPort();
+        if (audioport > 0)
+            sipCall.constructSdp();
+        if (sipCall.sdp != null && sipCall.sdp.flag) {
+            sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+            if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+            } else {
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+            }
+            sipCall.sdp.setCodec(
+                    SIPStack.SIP_MEDIATYPE_AUDIO,
+                    RFC2833.payloadType,
+                    "telephone-event/8000");
+            sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+        }
+        String body = null;
+        sipCall.contenttypeH = "";
+        if (sipCall.sdp != null && sipCall.sdp.flag) {
+            sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+            if (SIPStack.bVideocommunication) {
+                body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(audioport + 2);
+            } else {
+                body = sipCall.sdp.getBodyString();
+            }
+            sipCall.contentlengthH = "Content-Length: " + body.length();
+        } else {
+            body = "";
+            sipCall.contentlengthH = "Content-Length: 0";
+        }
+        sipCall.callState = 1;
+        sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+        if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+            sipCall.message =
+                    String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            header +
+                            sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                            sipCall.contenttypeH +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                            body;
+        } else {
+            sipCall.message =
+                    String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            header +
+                            sipCall.contenttypeH +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                            body;
+        }
+        return true;
+    }
+
+    public boolean INVITEParser_action_0(SIPCall sipCall, String message) {
+        try {
+            SIPRequestLine requestLine = new SIPRequestLine(message);
+            if (requestLine != null &&
+                    sipCall != null &&
+                    sipCall.flag &&
+                    sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_OUT) {
+                SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                boolean bValidCall = false;
+                if (sipHeader != null && sipHeader.flag)
+                    if (sipHeader.headerValue != null &&
+                            sipHeader.headerValue.length() > 0 &&
+                            sipCall.callId != null &&
+                            sipHeader.headerValue.compareTo(sipCall.callId) == 0) {
+                        SIPHeader seqHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                        if (seqHeader != null && seqHeader.callSequenceNumber() == sipCall.CSEQ_NUMBER) {
+                            sipCall.responseCode = requestLine.code;
+                            //Log.e(TAG, "[INVITEParser] ============ requestLine.code ============ ");
+                            return true;
+                        }
+                    }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean ACKParser_action_0(SIPCall sipCall, String message) {
+        try {
+            if (sipCall.callState == 23 ||
+                    sipCall.callState == 24) {
+                SIPRequestLine requestLine = new SIPRequestLine(message);
+                if (requestLine != null) {
+                    SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                    boolean bValidCall = false;
+                    if (sipHeader != null && sipHeader.flag)
+                        if (sipHeader.headerValue != null &&
+                                sipHeader.headerValue.length() > 0 &&
+                                sipCall.callId != null &&
+                                sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                            bValidCall = true;
+                    if (bValidCall) {
+                        sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                        if (sipHeader != null && sipHeader.flag) {
+                            sipCall.ACK_CSEQ = sipHeader.callSequenceNumber();
+                            sipCall.callMode = SIPStack.SIP_CALLMODE_BASIC;
+                            sipCall.callState = 7;
+                            sipCall.resetUpdateheaders();
+                            return true;
+                        }
+                    }
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean ACKParser_action_1(SIPCall sipCall, String message) {
+        try {
+            SIPRequestLine requestLine = new SIPRequestLine(message);
+            if (requestLine != null) {
+                boolean bValidCall = false;
+                SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                if (sipHeader != null && sipHeader.flag)
+                    if (sipHeader.headerValue != null &&
+                            sipHeader.headerValue.length() > 0 &&
+                            sipCall.callId != null &&
+                            sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                        bValidCall = true;
+                if (bValidCall) {
+                    sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                    if (sipHeader != null && sipHeader.flag) {
+                        sipCall.ACK_CSEQ = sipHeader.callSequenceNumber();
+                        sipCall.callState = 7;
+                        return true;
+                    }
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean ACKParser_action_2(SIPCall sipCall, String message) {
+        try {
+            boolean bValidCall = false;
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag)
+                if (sipHeader.headerValue != null &&
+                        sipHeader.headerValue.length() > 0 &&
+                        sipCall.callId != null &&
+                        sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                    return true;
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean CANCELParser_action_0(SIPCall sipCall, String message) {
+        try {
+            SIPRequestLine requestLine = new SIPRequestLine(message);
+            if (requestLine != null) {
+                SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+                boolean bValidCall = false;
+                if (sipHeader != null && sipHeader.flag)
+                    if (sipHeader.headerValue != null &&
+                            sipHeader.headerValue.length() > 0 &&
+                            sipCall.callId != null &&
+                            sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                        bValidCall = true;
+                if (bValidCall) {
+                    sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+                    if (sipHeader != null && sipHeader.flag) {
+                        sipCall.CANCEL_CSEQ = sipHeader.callSequenceNumber();
+                        sipCall.callState = 12;
+                        return true;
+                    }
+                }
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public boolean CANCELParser_action_1(SIPCall sipCall, String message) {
+        try {
+            SIPRequestLine requestLine = new SIPRequestLine(message);
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            boolean bValidCall = false;
+            if (sipHeader != null && sipHeader.flag)
+                if (sipHeader.headerValue != null &&
+                        sipHeader.headerValue.length() > 0 &&
+                        sipCall.callId != null &&
+                        sipHeader.headerValue.compareTo(sipCall.callId) == 0)
+                    bValidCall = true;
+            if (bValidCall) {
+                if (requestLine.code != 401);
+                return true;
+            }
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public String makeAcceptCancelRequest(SIPCall sipCall, String message) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            sipCall.BYE_CSEQ = sipCall.ACK_CSEQ;
+            String commandLine = null;
+            String viaH = null;
+            String maxforwardH = null;
+            String contactH = null;
+            String toH = null;
+            String fromH = null;
+            String callidH = null;
+            String cseqH = null;
+            String expiresH = null;
+            String allowH = null;
+            String useragentH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 200 " + SIPStack.getResponseDescription(200) + SIPStack.SIP_LINE_END;
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_VIA);
+            if (sipHeader != null && sipHeader.flag) {
+                viaH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                viaH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipHeader != null && sipHeader.flag) {
+                fromH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                fromH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipHeader != null && sipHeader.flag) {
+                toH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+                if (toH.indexOf("tag=") < 0)
+                    toH = String.valueOf(sipHeader.header) + ";tag=" + SIPStack.newTag() + SIPStack.SIP_LINE_END;
+            } else {
+                toH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag) {
+                callidH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                callidH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipHeader != null && sipHeader.flag) {
+                sipCall.CANCEL_CSEQ = sipHeader.callSequenceNumber();
+                cseqH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                cseqH = "";
+            }
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaH +
+                            fromH +
+                            toH +
+                            callidH +
+                            cseqH +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendProgressingwithbody(SIPCall sipCall) {
+        try {
+            String commandLine = null;
+            String contactH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 183 " + SIPStack.getResponseDescription(183) + SIPStack.SIP_LINE_END;
+            String viaString = "";
+            if (sipCall.viaArray.length() > 0)
+                viaString = sipCall.viaArray.toString();
+            String routeString = "";
+            if (sipCall.recordrouteArray.length() > 0)
+                routeString = sipCall.recordrouteArray.toString();
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            String contenttypeString = "";
+            String bodyString = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                String body = "";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getFinalBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getFinalBodyString();
+                }
+                if (body != null && body.length() > 0) {
+                    bodyString = body;
+                    contenttypeString = "Content-Type: application/SDP\r\n";
+                }
+            }
+            contentlengthH = "Content-Length: " + bodyString.length() + SIPStack.SIP_LINE_END;
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaString +
+                            routeString +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            contenttypeString +
+                            contentlengthH + SIPStack.SIP_LINE_END +
+                            bodyString;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendProgressing(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            String commandLine = null;
+            String contactH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 180 " + SIPStack.getResponseDescription(180) + SIPStack.SIP_LINE_END;
+            String viaString = "";
+            if (sipCall.viaArray.length() > 0)
+                viaString = sipCall.viaArray.toString();
+            String routeString = "";
+            if (sipCall.recordrouteArray != null &&
+                    sipCall.recordrouteArray.length() > 0)
+                routeString = sipCall.recordrouteArray.toString();
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaString +
+                            routeString +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendProceeding(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            String commandLine = null;
+            String contactH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 100 " + SIPStack.getResponseDescription(100) + SIPStack.SIP_LINE_END;
+            String viaString = "";
+            if (sipCall.viaArray.length() > 0)
+                viaString = sipCall.viaArray.toString();
+            String routeString = "";
+            if (sipCall.recordrouteArray != null &&
+                    sipCall.recordrouteArray.length() > 0)
+                routeString = sipCall.recordrouteArray.toString();
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaString +
+                            routeString +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendAccept(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN &&
+                    sipCall.callState == 2) {
+                String commandLine = null;
+                String contactH = null;
+                String contentlengthH = null;
+                commandLine = "SIP/2.0 200 " + SIPStack.getResponseDescription(200) + SIPStack.SIP_LINE_END;
+                String viaString = "";
+                if (sipCall.viaArray.length() > 0)
+                    viaString = sipCall.viaArray.toString();
+                String routeString = "";
+                if (sipCall.recordrouteArray.length() > 0)
+                    routeString = sipCall.recordrouteArray.toString();
+                if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                    contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+                } else {
+                    contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                }
+                String contenttypeString = "";
+                String bodyString = "";
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    String body = "";
+                    if (SIPStack.bVideocommunication) {
+                        body = String.valueOf(sipCall.sdp.getFinalBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                    } else {
+                        body = sipCall.sdp.getFinalBodyString();
+                    }
+                    if (body != null && body.length() > 0) {
+                        bodyString = body;
+                        contenttypeString = "Content-Type: application/SDP\r\n";
+                    }
+                }
+                contentlengthH = "Content-Length: " + bodyString.length() + SIPStack.SIP_LINE_END;
+                String sendmessage =
+                        String.valueOf(commandLine) +
+                                viaString +
+                                routeString +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                contactH + SIPStack.SIP_LINE_END +
+                                contenttypeString +
+                                contentlengthH + SIPStack.SIP_LINE_END +
+                                bodyString;
+                return sendmessage;
+            }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public String makeDirectsendAccept(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN &&
+                    sipCall.callState == 2) {
+                String commandLine = null;
+                String contactH = null;
+                String contentlengthH = null;
+                commandLine = "SIP/2.0 200 " + SIPStack.getResponseDescription(200) + SIPStack.SIP_LINE_END;
+                String viaString = "";
+                if (sipCall.viaArray.length() > 0)
+                    viaString = sipCall.viaArray.toString();
+                String routeString = "";
+                if (sipCall.recordrouteArray.length() > 0)
+                    routeString = sipCall.recordrouteArray.toString();
+                if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                    contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+                } else {
+                    contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                }
+                String contenttypeString = "";
+                String bodyString = "";
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    String body = "";
+                    if (SIPStack.bVideocommunication) {
+                        body = String.valueOf(sipCall.sdp.getFinalBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                    } else {
+                        body = sipCall.sdp.getFinalBodyString();
+                    }
+                    if (body != null && body.length() > 0) {
+                        bodyString = body;
+                        contenttypeString = "Content-Type: application/SDP\r\n";
+                    }
+                }
+                contentlengthH = "Content-Length: " + bodyString.length() + SIPStack.SIP_LINE_END;
+                String sendmessage =
+                        String.valueOf(commandLine) +
+                                viaString +
+                                routeString +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                contactH + SIPStack.SIP_LINE_END +
+                                contenttypeString +
+                                contentlengthH + SIPStack.SIP_LINE_END +
+                                bodyString;
+                return sendmessage;
+            }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public boolean makeCallMake(SIPCall sipCall, String number) {
+        try {
+            String header = "";
+            if (sipCall == null || sipCall.flag)
+                return false;
+            sipCall.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+            SIPStack.SIP_SEQUENCE_INVITE++;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            if (!sipCall.activeCallHandle(
+                    this.id,
+                    this.cid,
+                    this.authid,
+                    this.authpassword,
+                    number,
+                    this.serverIp,
+                    this.serverPort,
+                    this.serverDomain,
+                    this.localIp,
+                    this.localPort))
+                return false;
+            if (number.length() <= 0)
+                return false;
+            sipCall.commandLine = "INVITE sip:" + number + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            Date today = new Date();
+            sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            sipCall.toH = "To: \"" + number + "\"<sip:" + number + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            sipCall.fromTag = SIPStack.newTag();
+            sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            sipCall.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+            sipCall.callidH = "Call-ID: " + sipCall.callId;
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            if (sipCall.cid != null && sipCall.cid.length() > 0) {
+                sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                sipCall.passertedidentityH = null;
+                header = "";
+            }
+            int audioport = SIPStack.getFreeAudioRtpPort();
+            if (audioport > 0)
+                sipCall.constructSdp();
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711U,
+                            "PCMU/8000");
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711A,
+                            "PCMA/8000");
+                } else {
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711A,
+                            "PCMA/8000");
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711U,
+                            "PCMU/8000");
+                }
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        RFC2833.payloadType,
+                        "telephone-event/8000");
+                sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 1;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+                return true;
+            }
+            sipCall.message =
+                    String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            header +
+                            sipCall.contenttypeH +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                            body;
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeSendReInvite(SIPCall sipCall) {
+        try {
+            String header = null;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.callState = 1;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            if (sipCall.cid != null && sipCall.cid.length() > 0) {
+                sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                sipCall.passertedidentityH = null;
+                header = "";
+            }
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+                return true;
+            }
+            sipCall.message =
+                    String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            header +
+                            sipCall.contenttypeH +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                            body;
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public String makeRejectCall(SIPCall sipCall, int code) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN)
+                if (sipCall.callState == 2 ||
+                        sipCall.callState == 12) {
+                    String commandLine = null;
+                    String contactH = null;
+                    String contentlengthH = null;
+                    commandLine = "SIP/2.0 " + code + " " + SIPStack.getResponseDescription(code) + SIPStack.SIP_LINE_END;
+                    String viaString = "";
+                    if (sipCall.viaArray.length() > 0)
+                        viaString = sipCall.viaArray.toString();
+                    String routeString = "";
+                    if (sipCall.recordrouteArray.length() > 0)
+                        routeString = sipCall.recordrouteArray.toString();
+                    if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                        contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+                    } else {
+                        contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                    }
+                    contentlengthH = "Content-Length: 0" + SIPStack.SIP_LINE_END;
+                    String sendmessage =
+                            String.valueOf(commandLine) +
+                                    viaString +
+                                    routeString +
+                                    sipCall.fromH + SIPStack.SIP_LINE_END +
+                                    sipCall.toH + SIPStack.SIP_LINE_END +
+                                    sipCall.callidH + SIPStack.SIP_LINE_END +
+                                    sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                    contactH + SIPStack.SIP_LINE_END +
+                                    contentlengthH + SIPStack.SIP_LINE_END;
+                    return sendmessage;
+                }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public String makeRejectCall(SIPCall sipCall, int code, String contact) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN)
+                if (sipCall.callState == 2 ||
+                        sipCall.callState == 12) {
+                    String commandLine = null;
+                    String contactH = null;
+                    String contentlengthH = null;
+                    commandLine = "SIP/2.0 " + code + " " + SIPStack.getResponseDescription(code) + SIPStack.SIP_LINE_END;
+                    String viaString = "";
+                    if (sipCall.viaArray.length() > 0)
+                        viaString = sipCall.viaArray.toString();
+                    String routeString = "";
+                    if (sipCall.recordrouteArray.length() > 0)
+                        routeString = sipCall.recordrouteArray.toString();
+                    contactH = "Contact: <" + contact + ">";
+                    contentlengthH = "Content-Length: 0" + SIPStack.SIP_LINE_END;
+                    String sendmessage =
+                            String.valueOf(commandLine) +
+                                    viaString +
+                                    routeString +
+                                    sipCall.fromH + SIPStack.SIP_LINE_END +
+                                    sipCall.toH + SIPStack.SIP_LINE_END +
+                                    sipCall.callidH + SIPStack.SIP_LINE_END +
+                                    sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                    contactH + SIPStack.SIP_LINE_END +
+                                    contentlengthH + SIPStack.SIP_LINE_END;
+                    return sendmessage;
+                }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public String makeRejectCall(String message, int code, String localIp, int localPort, String remoteIp, int remotePort) {
+        try {
+            if (message == null || message.length() == 0 || remoteIp == null || remoteIp.length() == 0 ||
+                    remotePort <= 0)
+                return "";
+            String viaH = "";
+            StringBuffer viaArray = new StringBuffer();
+            String routeH = "";
+            StringBuffer routeArray = new StringBuffer();
+            String recordrouteH = "";
+            StringBuffer recordrouteArray = new StringBuffer();
+            String contactH = "";
+            String fromH = "";
+            String callidH = "";
+            String cseqH = "";
+            String contentlengthH = "";
+            StringTokenizer tokenArray = new StringTokenizer(message, SIPStack.SIP_LINE_END, true);
+            while (tokenArray.hasMoreTokens()) {
+                String token = tokenArray.nextToken().trim();
+                if (token.length() <= 0 ||
+                        token.compareTo("\r") == 0 ||
+                        token.compareTo("\n") == 0)
+                    continue;
+                if (token.startsWith("From: ")) {
+                    fromH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("f: ")) {
+                    fromH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("To: ")) {
+                    if (token.indexOf("tag=") < 0) {
+                        this.toH = String.valueOf(token) + ";tag=" + (new Date()).getTime() + SIPStack.SIP_LINE_END;
+                        continue;
+                    }
+                    this.toH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("t: ")) {
+                    if (token.indexOf("tag=") < 0) {
+                        this.toH = String.valueOf(token) + ";tag=" + (new Date()).getTime() + SIPStack.SIP_LINE_END;
+                        continue;
+                    }
+                    this.toH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("Via: ")) {
+                    if (viaH == null || viaH.length() == 0) {
+                        viaH = token;
+                        int iS = token.indexOf(";rport=");
+                        if (iS > 0 && token.indexOf(";received=") < 0) {
+                            String s1 = token.substring(0, iS);
+                            int iS_ = token.indexOf(";", iS + 1);
+                            String s2 = null;
+                            if (iS_ > 0) {
+                                s2 = token.substring(iS_ + 1);
+                                if (s1 != null && s2 != null) {
+                                    viaH = String.valueOf(s1) + ";" + s2;
+                                } else if (s1 != null) {
+                                    viaH = s1;
+                                }
+                            } else {
+                                viaH = s1;
+                            }
+                            if (viaH != null && viaH.length() > 0)
+                                viaH = String.valueOf(viaH) + ";received=" + remoteIp + ";rport=" + remotePort;
+                        }
+                        if (viaH != null && viaH.length() > 0)
+                            viaArray.append(String.valueOf(viaH) + SIPStack.SIP_LINE_END);
+                        continue;
+                    }
+                    viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                if (token.startsWith("v: ")) {
+                    if (viaH == null || viaH.length() == 0) {
+                        viaH = token;
+                        int iS = token.indexOf(";rport=");
+                        if (iS > 0 && token.indexOf(";received=") < 0) {
+                            String s1 = token.substring(0, iS);
+                            int iS_ = token.indexOf(";", iS + 1);
+                            String s2 = null;
+                            if (iS_ > 0) {
+                                s2 = token.substring(iS_ + 1);
+                                if (s1 != null && s2 != null) {
+                                    viaH = String.valueOf(s1) + ";" + s2;
+                                } else if (s1 != null) {
+                                    viaH = s1;
+                                }
+                            } else {
+                                viaH = s1;
+                            }
+                            if (viaH != null && viaH.length() > 0)
+                                viaH = String.valueOf(viaH) + ";received=" + remoteIp + ";rport=" + remotePort;
+                        }
+                        if (viaH != null && viaH.length() > 0)
+                            viaArray.append(String.valueOf(viaH) + SIPStack.SIP_LINE_END);
+                        continue;
+                    }
+                    viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                if (token.startsWith("Record-Route: ")) {
+                    if (recordrouteH == null || recordrouteH.length() == 0) {
+                        routeH = null;
+                        routeArray = new StringBuffer();
+                        recordrouteH = token;
+                        recordrouteArray.append(String.valueOf(recordrouteH) + SIPStack.SIP_LINE_END);
+                        routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                        continue;
+                    }
+                    recordrouteArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                    routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                if (token.startsWith("Call-ID: ")) {
+                    callidH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("i: ")) {
+                    callidH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("CSeq: ")) {
+                    cseqH = String.valueOf(token) + SIPStack.SIP_LINE_END;
+                    continue;
+                }
+                if (token.startsWith("Content-Length: ")) {
+                    contentlengthH = "Content-Length: 0\r\n";
+                    continue;
+                }
+                if (token.startsWith("l: "))
+                    contentlengthH = "Content-Length: 0\r\n";
+            }
+            String commandLine = "SIP/2.0 " + code + " " + SIPStack.getResponseDescription(code) + SIPStack.SIP_LINE_END;
+            String viaString = "";
+            if (viaArray.length() > 0)
+                viaString = viaArray.toString();
+            String routeString = "";
+            if (recordrouteArray.length() > 0)
+                routeString = recordrouteArray.toString();
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                contactH = "Contact: <sip:" + this.id + "@" + localIp + ":" + localPort + ">";
+            }
+            contentlengthH = "Content-Length: 0" + SIPStack.SIP_LINE_END;
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaString +
+                            routeString +
+                            fromH +
+                            this.toH +
+                            callidH +
+                            cseqH +
+                            contactH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendUpdateAccept(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN &&
+                    sipCall.callState == 23) {
+                String commandLine = null;
+                String contactH = null;
+                String contentlengthH = null;
+                commandLine = "SIP/2.0 200 " + SIPStack.getResponseDescription(200) + SIPStack.SIP_LINE_END;
+                String viaString = "";
+                if (sipCall.viaArray.length() > 0)
+                    viaString = sipCall.viaArray.toString();
+                String routeString = "";
+                if (sipCall.recordrouteArray.length() > 0)
+                    routeString = sipCall.recordrouteArray.toString();
+                if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                    sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+                } else {
+                    sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                }
+                String contenttypeString = "";
+                String bodyString = "";
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    String body = sipCall.sdp.getFinalBodyString();
+                    if (body != null && body.length() > 0) {
+                        bodyString = body;
+                        contenttypeString = "Content-Type: application/SDP\r\n";
+                    }
+                }
+                contentlengthH = "Content-Length: " + bodyString.length() + SIPStack.SIP_LINE_END;
+                String sendmessage =
+                        String.valueOf(commandLine) +
+                                viaString +
+                                routeString +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                contactH + SIPStack.SIP_LINE_END +
+                                contenttypeString +
+                                contentlengthH + SIPStack.SIP_LINE_END +
+                                bodyString;
+                return sendmessage;
+            }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public boolean makeSendRedirectCall(SIPCall sipCall, String message) {
+        try {
+            String header = null;
+            if (message == null || message.length() == 0)
+                return false;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            SIPCONTACTHeader contactHeader = new SIPCONTACTHeader(message);
+            if (contactHeader == null || !contactHeader.flag)
+                return false;
+            sipCall.initializeRedirectCall();
+            sipCall.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+            SIPStack.SIP_SEQUENCE_INVITE++;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            if (contactHeader != null && contactHeader.sipuri != null &&
+                    contactHeader.sipuri.length() > 0) {
+                sipCall.commandLine = "INVITE " + contactHeader.sipuri + " SIP/2.0";
+                sipCall.remoteIp = contactHeader.ip;
+                sipCall.remotePort = contactHeader.port;
+                sipCall.dnis = contactHeader.username;
+                sipCall.serverDomain = contactHeader.ip;
+                sipCall.serverPort = contactHeader.port;
+                BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                if (contactHeader.username.startsWith("lobby")) {
+                    BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_LOBBY;
+                } else if (contactHeader.username.startsWith("office")) {
+                    BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_GUARD;
+                }
+            } else {
+                return false;
+            }
+            Date today = new Date();
+            sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            sipCall.toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            sipCall.fromTag = SIPStack.newTag();
+            sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_LOBBY) {
+                String postFix = "";
+                if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                    postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                    postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                } else {
+                    postFix = BSSVideo.HNS_POSTFIX_LOBBY;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+                }
+                sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_LOBBY) + SIPStack.BSSMD5Get(this.viaH) +
+                        SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+                sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+                BSSVideo.bProgressvideooffer = true;
+            } else if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                String postFix = "";
+                if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                    postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                    postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                } else {
+                    postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+                }
+                sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_GUARD) + SIPStack.BSSMD5Get(this.viaH) +
+                        SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+                sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                BSSVideo.bProgressvideooffer = true;
+            } else if (BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                String postFix = "";
+                if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_GUARD) {
+                    postFix = BSSVideo.HNS_POSTFIX_GUARD;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                    BSSVideo.bProgressvideooffer = true;
+                } else if (BSSVideo.HNS_SERVICE_RECEIVER_SELECTED == BSSVideo.HNS_SERVICE_NEIGHBOR) {
+                    postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                    BSSVideo.bProgressvideooffer = true;
+                } else {
+                    postFix = BSSVideo.HNS_POSTFIX_NEIGHBOR;
+                    sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_ORIGINATOR_SELECTED;
+                    BSSVideo.bProgressvideooffer = false;
+                }
+                sipCall.callId = String.valueOf(BSSVideo.HNS_PREFIX_NEIGHBOR) + SIPStack.BSSMD5Get(this.viaH) +
+                        SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + "." + postFix;
+                sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+            } else {
+                sipCall.callId = String.valueOf(SIPStack.BSSMD5Get(this.viaH)) + SIPStack.BSSMD5Get("1198602188") + today.getSeconds() + ".";
+                sipCall.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+                sipCall.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                BSSVideo.bProgressvideooffer = false;
+            }
+            sipCall.callidH = "Call-ID: " + sipCall.callId;
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            if (sipCall.cid != null && sipCall.cid.length() > 0) {
+                sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                sipCall.passertedidentityH = null;
+                header = "";
+            }
+            int audioport = SIPStack.getFreeAudioRtpPort();
+            if (audioport > 0)
+                sipCall.constructSdp();
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711U,
+                            "PCMU/8000");
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711A,
+                            "PCMA/8000");
+                } else {
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711A,
+                            "PCMA/8000");
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711U,
+                            "PCMU/8000");
+                }
+                sipCall.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        RFC2833.payloadType,
+                        "telephone-event/8000");
+                sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 1;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            sipCall.message =
+                    String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                            sipCall.viaH + SIPStack.SIP_LINE_END +
+                            sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                            sipCall.contactH + SIPStack.SIP_LINE_END +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            sipCall.allowH + SIPStack.SIP_LINE_END +
+                            sipCall.useragentH + SIPStack.SIP_LINE_END +
+                            header +
+                            sipCall.contenttypeH +
+                            sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                            body;
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeReactionForWWWAUTHENTICATE(SIPCall sipCall, String message) {
+        try {
+            String header = null;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipCall.CSEQ_NUMBER = ++SIPStack.SIP_SEQUENCE_INVITE;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            sipCall.authorizationINVITEH = "";
+            sipCall.authorizationCANCELH = "";
+            sipCall.authorizationBYEH = "";
+            sipCall.authorizationACKH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE);
+            if (sipHeader == null || !sipHeader.flag)
+                sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE);
+            if (sipHeader != null && sipHeader.flag) {
+                SIPAUTHENTICATEHeader authHeader =
+                        new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE);
+                if (authHeader == null || !authHeader.flag)
+                    authHeader = new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE);
+                if (authHeader != null && authHeader.flag)
+                    if (authHeader.nonceValue.length() > 0 && authHeader.realmValue.length() > 0) {
+                        String qop = authHeader.qopValue;
+                        String uri = "sip:" + this.serverDomain + ":" + this.serverPort;
+                        sipCall.authorizationINVITEH = getAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_INVITE);
+                        sipCall.authorizationCANCELH = getAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_CANCEL);
+                        sipCall.authorizationBYEH = getAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_BYE);
+                        sipCall.authorizationACKH = getAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_ACK);
+                    }
+            }
+            sipCall.commandLine = "INVITE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            sipCall.toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            sipCall.fromTag = SIPStack.newTag();
+            sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            if (sipCall.cid != null && sipCall.cid.length() > 0) {
+                sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                sipCall.passertedidentityH = null;
+                header = "";
+            }
+            if (sipCall.sdp == null) {
+                int audioport = SIPStack.getFreeAudioRtpPort();
+                if (audioport > 0)
+                    sipCall.constructSdp();
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                    if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                    } else {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                    }
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            RFC2833.payloadType,
+                            "telephone-event/8000");
+                    sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+                }
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 1;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            sipCall.message = "";
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeReactionForPROXYAUTHENTICATE(SIPCall sipCall, String message) {
+        try {
+            String header = null;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipCall.CSEQ_NUMBER = ++SIPStack.SIP_SEQUENCE_INVITE;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            sipCall.authorizationINVITEH = "";
+            sipCall.authorizationCANCELH = "";
+            sipCall.authorizationBYEH = "";
+            sipCall.authorizationACKH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE);
+            if (sipHeader != null && sipHeader.flag) {
+                SIPAUTHENTICATEHeader authHeader =
+                        new SIPAUTHENTICATEHeader(sipHeader.header, SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE);
+                if (authHeader.flag)
+                    if (authHeader.nonceValue.length() > 0 && authHeader.realmValue.length() > 0) {
+                        String qop = authHeader.qopValue;
+                        String uri = "sip:" + this.serverDomain + ":" + this.serverPort;
+                        sipCall.authorizationINVITEH = getProxyAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_INVITE);
+                        sipCall.authorizationCANCELH = getProxyAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_CANCEL);
+                        sipCall.authorizationBYEH = getProxyAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_BYE);
+                        sipCall.authorizationACKH = getProxyAuthorizationHeader(
+                                qop,
+                                this.authid,
+                                authHeader.realmValue,
+                                this.authpassword, uri,
+                                authHeader.nonceValue,
+                                SIPStack.SIP_METHODTYPE_ACK);
+                    }
+            }
+            sipCall.commandLine = "INVITE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            sipCall.toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            sipCall.fromTag = SIPStack.newTag();
+            sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+            if (sipCall.cid != null && sipCall.cid.length() > 0) {
+                sipCall.passertedidentityH = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+                header = "P-Asserted-Identity: <sip:" + sipCall.cid + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                sipCall.passertedidentityH = null;
+                header = "";
+            }
+            if (sipCall.sdp == null) {
+                int audioport = SIPStack.getFreeAudioRtpPort();
+                if (audioport > 0)
+                    sipCall.constructSdp();
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                    if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                    } else {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                    }
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            RFC2833.payloadType,
+                            "telephone-event/8000");
+                    sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+                }
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 1;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                header +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public String makeRedirectIncomingCall(SIPCall sipCall, String redirectId) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (redirectId == null || redirectId.length() == 0)
+                return "";
+            if (sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN)
+                if (sipCall.callState == 2 ||
+                        sipCall.callState == 12) {
+                    String commandLine = null;
+                    String contactH = null;
+                    String contentlengthH = null;
+                    commandLine = "SIP/2.0 302 " + SIPStack.getResponseDescription(302) + SIPStack.SIP_LINE_END;
+                    String viaString = "";
+                    if (sipCall.viaArray.length() > 0)
+                        viaString = sipCall.viaArray.toString();
+                    String routeString = "";
+                    if (sipCall.recordrouteArray.length() > 0)
+                        routeString = sipCall.recordrouteArray.toString();
+                    contactH = "Contact: <sip:" + redirectId + "@" + this.serverIp + ":" + this.serverPort + ">";
+                    contentlengthH = "Content-Length: 0" + SIPStack.SIP_LINE_END;
+                    String sendmessage =
+                            String.valueOf(commandLine) +
+                                    viaString +
+                                    routeString +
+                                    sipCall.fromH + SIPStack.SIP_LINE_END +
+                                    sipCall.toH + SIPStack.SIP_LINE_END +
+                                    sipCall.callidH + SIPStack.SIP_LINE_END +
+                                    sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                    contactH + SIPStack.SIP_LINE_END +
+                                    contentlengthH + SIPStack.SIP_LINE_END;
+                    return sendmessage;
+                }
+        } catch (Exception exception) {}
+        return "";
+    }
+
+    public String makeSendProgressing(SIPCall sipCall, String body) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            if (body == null || body.length() <= 0)
+                return "";
+            String commandLine = null;
+            String contactH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 183 " + SIPStack.getResponseDescription(183) + SIPStack.SIP_LINE_END;
+            String viaString = "";
+            if (sipCall.viaArray.length() > 0)
+                viaString = sipCall.viaArray.toString();
+            SIPHeader sipHeader = new SIPHeader(this.message, SIPStack.SIP_HEADERTYPE_VIA);
+            if (sipHeader != null && sipHeader.flag) {
+                this.viaH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                this.viaH = "";
+            }
+            String routeString = "";
+            if (sipCall.recordrouteArray != null &&
+                    sipCall.recordrouteArray.length() > 0)
+                routeString = sipCall.recordrouteArray.toString();
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            contentlengthH = "Content-Length: " + body.length() + SIPStack.SIP_LINE_END;
+            String contenttypeH = "";
+            if (body != null && body.length() > 0)
+                contenttypeH = "Content-Type: application/SDP" + SIPStack.SIP_LINE_END;
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaString +
+                            routeString +
+                            sipCall.fromH + SIPStack.SIP_LINE_END +
+                            sipCall.toH + SIPStack.SIP_LINE_END +
+                            sipCall.callidH + SIPStack.SIP_LINE_END +
+                            sipCall.cseqH + SIPStack.SIP_LINE_END +
+                            contactH + SIPStack.SIP_LINE_END +
+                            contenttypeH +
+                            contentlengthH +
+                            SIPStack.SIP_LINE_END +
+                            body;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public boolean makeSendAck(SIPCall sipCall, String message) {
+        try {
+            sipCall.routeIp = "";
+            sipCall.routePort = 5060;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipCall.ACK_CSEQ = sipCall.CSEQ_NUMBER;
+            sipCall.reverseRecordRoute(message);
+            if (sipCall.remoteContactUri != null && sipCall.remoteContactUri.length() > 0) {
+                sipCall.commandLine = "ACK " + sipCall.remoteContactUri + " SIP/2.0";
+            } else {
+                sipCall.commandLine = "ACK sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            }
+            if (sipCall.viaH == null || sipCall.viaH.length() == 0) {
+                if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                    sipCall.viaBranch = SIPStack.getViaBranch();
+                sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            }
+            sipCall.cseqH = "CSeq: " + sipCall.ACK_CSEQ + " ACK";
+            sipCall.contentlengthH = "Content-Length: 0";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            String routeString = "";
+            if (sipCall.routeArray != null &&
+                    sipCall.routeArray.length() > 0) {
+                routeString = sipCall.routeArray.toString();
+                if (sipCall.routeH != null && sipCall.routeH.length() > 0) {
+                    SIPROUTEHeader header = new SIPROUTEHeader(sipCall.routeH);
+                    if (header != null && header.flag) {
+                        sipCall.routeIp = header.getIp();
+                        sipCall.routePort = header.getPort();
+                    }
+                }
+            }
+            if (sipCall.authorizationACKH != null && sipCall.authorizationACKH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.authorizationACKH + SIPStack.SIP_LINE_END +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeSendFinalAck(SIPCall sipCall, String message) {
+        try {
+            String fromH = null;
+            String toH = null;
+            String callidH = null;
+            String viaH = null;
+            String commandLine = null;
+            String contentlengthH = null;
+            String cseqH = null;
+            SIPHeader sipheader = null;
+            sipCall.routeIp = "";
+            sipCall.routePort = 5060;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                fromH = new String(sipheader.header);
+            } else {
+                return false;
+            }
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                toH = new String(sipheader.header);
+            } else {
+                return false;
+            }
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                callidH = new String(sipheader.header);
+            } else {
+                return false;
+            }
+            int ACK_CSEQ = sipCall.CSEQ_NUMBER;
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipheader != null && sipheader.flag && sipheader.callSequenceNumber() >= 0)
+                ACK_CSEQ = sipheader.callSequenceNumber();
+            sipCall.reverseRecordRoute(message);
+            if (sipCall.remoteContactUri != null && sipCall.remoteContactUri.length() > 0) {
+                commandLine = "ACK " + sipCall.remoteContactUri + " SIP/2.0";
+            } else {
+                commandLine = "ACK sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            }
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_VIA);
+            if (sipheader != null && sipheader.flag) {
+                viaH = new String(sipheader.header);
+                if (viaH != null && viaH.length() > 0) {
+                    String branch = "";
+                    int index = viaH.indexOf(";branch=");
+                    if (index > 0)
+                        branch = viaH.substring(index + 1);
+                    index = branch.indexOf(";");
+                    if (index > 0)
+                        branch = branch.substring(0, index);
+                    index = viaH.indexOf(";received=");
+                    if (index > 0)
+                        viaH = viaH.substring(0, index);
+                    index = viaH.indexOf(";rport=");
+                    if (index > 0)
+                        viaH = viaH.substring(0, index);
+                    viaH = String.valueOf(viaH) + ";" + branch;
+                }
+            }
+            if (viaH == null || viaH.length() == 0)
+                viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+            cseqH = "CSeq: " + ACK_CSEQ + " ACK";
+            contentlengthH = "Content-Length: 0";
+            String routeString = "";
+            if (sipCall.routeArray != null &&
+                    sipCall.routeArray.length() > 0) {
+                routeString = sipCall.routeArray.toString();
+                if (sipCall.routeH != null && sipCall.routeH.length() > 0) {
+                    SIPROUTEHeader header = new SIPROUTEHeader(sipCall.routeH);
+                    if (header != null && header.flag) {
+                        sipCall.routeIp = header.getIp();
+                        sipCall.routePort = header.getPort();
+                    }
+                }
+            }
+            if (sipCall.authorizationACKH != null && sipCall.authorizationACKH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                                fromH + SIPStack.SIP_LINE_END +
+                                toH + SIPStack.SIP_LINE_END +
+                                viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                callidH + SIPStack.SIP_LINE_END +
+                                cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.authorizationACKH + SIPStack.SIP_LINE_END +
+                                contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                sipCall.message =
+                        String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                                fromH + SIPStack.SIP_LINE_END +
+                                toH + SIPStack.SIP_LINE_END +
+                                viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                callidH + SIPStack.SIP_LINE_END +
+                                cseqH + SIPStack.SIP_LINE_END +
+                                contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public String makeSendFinalAck(SIPCall sipCall, String message, String remoteIp, int remotePort) {
+        try {
+            String fromH = null;
+            String toH = null;
+            String callidH = null;
+            String viaH = null;
+            String commandLine = null;
+            String contentlengthH = null;
+            String cseqH = null;
+            SIPHeader sipheader = null;
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                fromH = new String(sipheader.header);
+            } else {
+                return "";
+            }
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                toH = new String(sipheader.header);
+            } else {
+                return "";
+            }
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipheader != null && sipheader.flag && sipheader.header != null && sipheader.header.length() > 0) {
+                callidH = new String(sipheader.header);
+            } else {
+                return "";
+            }
+            int ACK_CSEQ = 0;
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipheader != null && sipheader.flag && sipheader.callSequenceNumber() >= 0)
+                ACK_CSEQ = sipheader.callSequenceNumber();
+            commandLine = "ACK sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            sipheader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_VIA);
+            if (sipheader != null && sipheader.flag) {
+                viaH = new String(sipheader.header);
+                if (viaH != null && viaH.length() > 0) {
+                    String branch = "";
+                    int index = viaH.indexOf(";branch=");
+                    if (index > 0)
+                        branch = viaH.substring(index + 1);
+                    index = branch.indexOf(";");
+                    if (index > 0)
+                        branch = branch.substring(0, index);
+                    index = viaH.indexOf(";received=");
+                    if (index > 0)
+                        viaH = viaH.substring(0, index);
+                    index = viaH.indexOf(";rport=");
+                    if (index > 0)
+                        viaH = viaH.substring(0, index);
+                    viaH = String.valueOf(viaH) + ";" + branch;
+                }
+            }
+            if (viaH == null || viaH.length() == 0)
+                viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + SIPStack.getViaBranch() + ";rport";
+            cseqH = "CSeq: " + ACK_CSEQ + " ACK";
+            contentlengthH = "Content-Length: 0";
+            String sendmessage =
+                    String.valueOf(commandLine) + SIPStack.SIP_LINE_END +
+                            fromH + SIPStack.SIP_LINE_END +
+                            toH + SIPStack.SIP_LINE_END +
+                            viaH + SIPStack.SIP_LINE_END +
+                            callidH + SIPStack.SIP_LINE_END +
+                            cseqH + SIPStack.SIP_LINE_END +
+                            contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public boolean makeSendRedirectFinalAck(SIPCall sipCall, String message) {
+        try {
+            sipCall.routeIp = "";
+            sipCall.routePort = 5060;
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            sipCall.ACK_CSEQ = sipCall.CSEQ_NUMBER;
+            sipCall.reverseRecordRoute(message);
+            sipCall.commandLine = "ACK sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            if (sipCall.viaH == null || sipCall.viaH.length() == 0) {
+                if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                    sipCall.viaBranch = SIPStack.getViaBranch();
+                sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            }
+            sipCall.cseqH = "CSeq: " + sipCall.ACK_CSEQ + " ACK";
+            sipCall.contentlengthH = "Content-Length: 0";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            String routeString = "";
+            if (sipCall.routeArray != null &&
+                    sipCall.routeArray.length() > 0) {
+                routeString = sipCall.routeArray.toString();
+                if (sipCall.routeH != null && sipCall.routeH.length() > 0) {
+                    SIPROUTEHeader header = new SIPROUTEHeader(sipCall.routeH);
+                    if (header != null && header.flag) {
+                        sipCall.routeIp = header.getIp();
+                        sipCall.routePort = header.getPort();
+                    }
+                }
+            }
+            if (sipCall.authorizationACKH != null && sipCall.authorizationACKH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.authorizationACKH + SIPStack.SIP_LINE_END +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                routeString +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public String makeSendByeResponse(SIPCall sipCall, String message) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            sipCall.BYE_CSEQ = sipCall.ACK_CSEQ;
+            String commandLine = null;
+            String viaH = null;
+            String toH = null;
+            String fromH = null;
+            String callidH = null;
+            String cseqH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 200 " + SIPStack.getResponseDescription(200) + SIPStack.SIP_LINE_END;
+            viaH = sipCall.getViaArray(message);
+            if (viaH == null || viaH.length() == 0)
+                viaH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipHeader != null && sipHeader.flag) {
+                fromH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                fromH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipHeader != null && sipHeader.flag) {
+                toH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+                if (toH.indexOf("tag=") < 0)
+                    toH = String.valueOf(sipHeader.header) + ";tag=" + SIPStack.newTag() + SIPStack.SIP_LINE_END;
+            } else {
+                toH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag) {
+                callidH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                callidH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipHeader != null && sipHeader.flag) {
+                sipCall.BYE_CSEQ = sipHeader.callSequenceNumber();
+                cseqH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                cseqH = "";
+            }
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaH +
+                            fromH +
+                            toH +
+                            callidH +
+                            cseqH +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendOptionsResponse(SIPCall sipCall, String message, int code) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return "";
+            String commandLine = null;
+            String viaH = null;
+            String toH = null;
+            String fromH = null;
+            String callidH = null;
+            String cseqH = null;
+            String allowH = null;
+            String useragentH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 " + code + " " + SIPStack.getResponseDescription(code) + SIPStack.SIP_LINE_END;
+            viaH = sipCall.getViaArray(message);
+            if (viaH == null || viaH.length() == 0)
+                viaH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipHeader != null && sipHeader.flag) {
+                fromH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                fromH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipHeader != null && sipHeader.flag) {
+                toH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+                if (toH.indexOf("tag=") < 0)
+                    toH = String.valueOf(sipHeader.header) + ";tag=" + SIPStack.newTag() + SIPStack.SIP_LINE_END;
+            } else {
+                toH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag) {
+                callidH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                callidH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipHeader != null && sipHeader.flag) {
+                cseqH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                cseqH = "";
+            }
+            allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO" + SIPStack.SIP_LINE_END;
+            useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o" + SIPStack.SIP_LINE_END;
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaH +
+                            fromH +
+                            toH +
+                            callidH +
+                            cseqH +
+                            allowH +
+                            useragentH +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public String makeSendInfoResponse(SIPCall sipCall, String message, int code) {
+        if (sipCall == null || !sipCall.flag)
+            return "";
+        try {
+            String commandLine = null;
+            String viaH = null;
+            String toH = null;
+            String fromH = null;
+            String callidH = null;
+            String cseqH = null;
+            String allowH = null;
+            String useragentH = null;
+            String contentlengthH = null;
+            commandLine = "SIP/2.0 " + code + " " + SIPStack.getResponseDescription(code) + SIPStack.SIP_LINE_END;
+            viaH = sipCall.getViaArray(message);
+            if (viaH == null || viaH.length() == 0)
+                viaH = "";
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_FROM);
+            if (sipHeader != null && sipHeader.flag) {
+                fromH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                fromH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_TO);
+            if (sipHeader != null && sipHeader.flag) {
+                toH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+                if (toH.indexOf("tag=") < 0)
+                    toH = String.valueOf(sipHeader.header) + ";tag=" + SIPStack.newTag() + SIPStack.SIP_LINE_END;
+            } else {
+                toH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag) {
+                callidH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                callidH = "";
+            }
+            sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CSEQ);
+            if (sipHeader != null && sipHeader.flag) {
+                cseqH = String.valueOf(sipHeader.header) + SIPStack.SIP_LINE_END;
+            } else {
+                cseqH = "";
+            }
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                this.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">" + SIPStack.SIP_LINE_END;
+            } else {
+                this.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">" + SIPStack.SIP_LINE_END;
+            }
+            allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO" + SIPStack.SIP_LINE_END;
+            useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o" + SIPStack.SIP_LINE_END;
+            contentlengthH = "Content-Length: 0\r\n";
+            String sendmessage =
+                    String.valueOf(commandLine) +
+                            viaH +
+                            fromH +
+                            toH +
+                            callidH +
+                            cseqH +
+                            this.contactH +
+                            allowH +
+                            useragentH +
+                            contentlengthH + SIPStack.SIP_LINE_END;
+            return sendmessage;
+        } catch (Exception exception) {
+            return "";
+        }
+    }
+
+    public boolean makeSendUpdate(SIPCall sipCall) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            String viaBranch = sipCall.viaBranch;
+            sipCall.setUpdateheaders("sendonly");
+            sipCall.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+            SIPStack.SIP_SEQUENCE_INVITE++;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            sipCall.commandLine = "INVITE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            sipCall.viaBranch = viaBranch;
+            if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            if (sipCall.toH == null || sipCall.toH.length() == 0)
+                sipCall.toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            if (sipCall.fromH == null || sipCall.fromH.length() == 0) {
+                sipCall.fromTag = SIPStack.newTag();
+                sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            }
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: " + SIPStack.USER_AGENT;
+            if (sipCall.sdp == null) {
+                int audioport = SIPStack.getFreeAudioRtpPort();
+                if (audioport > 0)
+                    sipCall.constructSdp();
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                    if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                    } else {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                    }
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            RFC2833.payloadType,
+                            "telephone-event/8000");
+                    sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+                }
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 20;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public boolean makeSendUpdate(SIPCall sipCall, String flow) {
+        try {
+            if (sipCall == null || !sipCall.flag)
+                return false;
+            String viaBranch = sipCall.viaBranch;
+            sipCall.setUpdateheaders(flow);
+            sipCall.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+            SIPStack.SIP_SEQUENCE_INVITE++;
+            if (SIPStack.SIP_SEQUENCE_INVITE > 65556)
+                SIPStack.SIP_SEQUENCE_INVITE = 1;
+            sipCall.commandLine = "INVITE sip:" + sipCall.dnis + "@" + this.serverDomain + ":" + this.serverPort + " SIP/2.0";
+            sipCall.viaBranch = viaBranch;
+            if (sipCall.viaBranch == null || sipCall.viaBranch.length() == 0)
+                sipCall.viaBranch = SIPStack.getViaBranch();
+            sipCall.viaH = "Via: SIP/2.0/UDP " + this.localIp + ":" + this.localPort + ";branch=" + sipCall.viaBranch + ";rport";
+            sipCall.maxforwardH = "Max-Forwards: 70";
+            if (this.ifIp != null && this.ifIp.length() > 0 && this.ifPort > 0) {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + this.ifIp + ":" + this.ifPort + ">";
+            } else {
+                sipCall.contactH = "Contact: <sip:" + this.id + "@" + sipCall.localIp + ":" + sipCall.localPort + ">";
+            }
+            if (sipCall.toH == null || sipCall.toH.length() == 0)
+                sipCall.toH = "To: \"" + sipCall.dnis + "\"<sip:" + sipCall.dnis + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">";
+            if (sipCall.fromH == null || sipCall.fromH.length() == 0) {
+                sipCall.fromTag = SIPStack.newTag();
+                sipCall.fromH = "From: \"" + sipCall.id + "\"<sip:" + sipCall.id + "@" + sipCall.serverDomain + ":" + sipCall.serverPort + ">;tag=" + sipCall.fromTag;
+            }
+            sipCall.cseqH = "CSeq: " + sipCall.CSEQ_NUMBER + " INVITE";
+            sipCall.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+            sipCall.useragentH = "User-Agent: " + SIPStack.USER_AGENT;
+            if (sipCall.sdp == null) {
+                int audioport = SIPStack.getFreeAudioRtpPort();
+                if (audioport > 0)
+                    sipCall.constructSdp();
+                if (sipCall.sdp != null && sipCall.sdp.flag) {
+                    sipCall.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+                    if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                    } else {
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711A,
+                                "PCMA/8000");
+                        sipCall.sdp.setCodec(
+                                SIPStack.SIP_MEDIATYPE_AUDIO,
+                                SIPStack.SIP_CODEC_G711U,
+                                "PCMU/8000");
+                    }
+                    sipCall.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            RFC2833.payloadType,
+                            "telephone-event/8000");
+                    sipCall.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+                }
+            }
+            String body = null;
+            sipCall.contenttypeH = "";
+            if (sipCall.sdp != null && sipCall.sdp.flag) {
+                sipCall.contenttypeH = "Content-Type: application/SDP\r\n";
+                if (SIPStack.bVideocommunication) {
+                    body = String.valueOf(sipCall.sdp.getBodyString()) + getVideomediadescription(sipCall.sdp.audioM.mediaPort + 2);
+                } else {
+                    body = sipCall.sdp.getBodyString();
+                }
+                sipCall.contentlengthH = "Content-Length: " + body.length();
+            } else {
+                body = "";
+                sipCall.contentlengthH = "Content-Length: 0";
+            }
+            sipCall.callState = 20;
+            sipCall.callDirection = SIPStack.SIP_CALLDIRECTION_OUT;
+            if (sipCall.authorizationINVITEH != null && sipCall.authorizationINVITEH.length() > 0) {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.authorizationINVITEH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            } else {
+                sipCall.message =
+                        String.valueOf(sipCall.commandLine) + SIPStack.SIP_LINE_END +
+                                sipCall.viaH + SIPStack.SIP_LINE_END +
+                                sipCall.maxforwardH + SIPStack.SIP_LINE_END +
+                                sipCall.contactH + SIPStack.SIP_LINE_END +
+                                sipCall.fromH + SIPStack.SIP_LINE_END +
+                                sipCall.toH + SIPStack.SIP_LINE_END +
+                                sipCall.callidH + SIPStack.SIP_LINE_END +
+                                sipCall.cseqH + SIPStack.SIP_LINE_END +
+                                sipCall.allowH + SIPStack.SIP_LINE_END +
+                                sipCall.useragentH + SIPStack.SIP_LINE_END +
+                                sipCall.contenttypeH +
+                                sipCall.contentlengthH + SIPStack.SIP_LINE_DOUBLEEND +
+                                body;
+            }
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public static String getCallfailReason(int finalCode) {
+        String desc = "";
+        switch (finalCode) {
+            case 200:
+                desc = "통화";
+                break;
+            case 300:
+                desc = "거절";
+                break;
+            case 301:
+                desc = "거절";
+                break;
+            case 302:
+                desc = "거절";
+                break;
+            case 305:
+                desc = "거절";
+                break;
+            case 380:
+                desc = "거절";
+                break;
+            case 400:
+                desc = "거절";
+                break;
+            case 401:
+                desc = "거절";
+                break;
+            case 402:
+                desc = "거절";
+                break;
+            case 403:
+                desc = "거절";
+                break;
+            case 404:
+                desc = "거절";
+                break;
+            case 405:
+                desc = "거절";
+                break;
+            case 406:
+                desc = "거절";
+                break;
+            case 407:
+                desc = "거절";
+                break;
+            case 408:
+                desc = "거절";
+                break;
+            case 409:
+                desc = "거절";
+                break;
+            case 410:
+                desc = "거절";
+                break;
+            case 411:
+                desc = "거절";
+                break;
+            case 413:
+                desc = "거절";
+                break;
+            case 414:
+                desc = "거절";
+                break;
+            case 415:
+                desc = "거절";
+                break;
+            case 420:
+                desc = "거절";
+                break;
+            case 421:
+                desc = "거절";
+                break;
+            case 423:
+                desc = "거절";
+                break;
+            case 480:
+                desc = "거절";
+                break;
+            case 481:
+                desc = "거절";
+                break;
+            case 482:
+                desc = "거절";
+                break;
+            case 483:
+                desc = "거절";
+                break;
+            case 484:
+                desc = "거절";
+                break;
+            case 485:
+                desc = "거절";
+                break;
+            case 486:
+                desc = "거절";
+                break;
+            case 487:
+                desc = "통화중";
+                break;
+            case 488:
+                desc = "거절";
+                break;
+            case 500:
+                desc = "거절";
+                break;
+            case 501:
+                desc = "거절";
+                break;
+            case 502:
+                desc = "거절";
+                break;
+            case 503:
+                desc = "거절";
+                break;
+            case 504:
+                desc = "거절";
+                break;
+            case 505:
+                desc = "거절";
+                break;
+            case 600:
+                desc = "거절";
+                break;
+            case 603:
+                desc = "거절";
+                break;
+            case 604:
+                desc = "거절";
+                break;
+            case 606:
+                desc = "거절";
+                break;
+            case 700:
+                desc = "통화종료";
+                break;
+        }
+        return desc;
+    }
+}

+ 21 - 0
WallPadCall/src/main/java/bssoft/stack/sip/Frequent.java

@@ -0,0 +1,21 @@
+package bssoft.stack.sip;
+
+public class Frequent {
+    public int _id;
+
+    public String phone;
+
+    public String name;
+
+    public Frequent() {
+        this._id = 0;
+        this.phone = "";
+        this.name = "";
+    }
+
+    public Frequent(int id, String phone, String name) {
+        this._id = id;
+        this.phone = phone;
+        this.name = name;
+    }
+}

+ 36 - 0
WallPadCall/src/main/java/bssoft/stack/sip/GetIpDns.java

@@ -0,0 +1,36 @@
+package bssoft.stack.sip;
+
+public class GetIpDns {
+    public String sipServerHost = "";
+
+    public String strId = "";
+
+    public String strCid = "";
+
+    public String strAuthid = "";
+
+    public String strAuthpassword = "";
+
+    public String strServerHost = "";
+
+    public String strServerDomain = "";
+
+    public int serverPort = 5060;
+
+    public boolean bSipAddressResolved = false;
+
+    public int sipTry = 0;
+
+    public GetIpDns() {
+        this.sipServerHost = "";
+        this.bSipAddressResolved = false;
+        this.sipTry = 0;
+        this.strId = "";
+        this.strCid = "";
+        this.strAuthid = "";
+        this.strAuthpassword = "";
+        this.strServerHost = "";
+        this.strServerDomain = "";
+        this.serverPort = 5060;
+    }
+}

+ 82 - 0
WallPadCall/src/main/java/bssoft/stack/sip/History.java

@@ -0,0 +1,82 @@
+package bssoft.stack.sip;
+
+public class History {
+    public int _id;
+
+    public String phone;
+
+    public String ani;
+
+    public String dnis;
+
+    public String name;
+
+    public String date;
+
+    public String direction;
+
+    public String code;
+
+    public String duration;
+
+    public String calltype;
+
+    public String callhandle;
+
+    public String check;
+
+    public String view;
+
+    public int count;
+
+    public History() {
+        this._id = 0;
+        this.phone = "";
+        this.ani = "";
+        this.dnis = "";
+        this.name = "";
+        this.date = "";
+        this.direction = "";
+        this.code = "";
+        this.duration = "";
+        this.calltype = "";
+        this.callhandle = "";
+        this.count = 0;
+        this.check = "0";
+        this.view = "0";
+    }
+
+    public History(int id, String phone, String ani, String dnis, String name, String date, String direction, String code, String duration, String calltype, String callhandle) {
+        this._id = id;
+        this.phone = phone;
+        this.ani = ani;
+        this.dnis = dnis;
+        this.name = name;
+        this.date = date;
+        this.direction = direction;
+        this.code = code;
+        this.duration = duration;
+        this.calltype = calltype;
+        this.callhandle = callhandle;
+        this.check = "0";
+        this.view = "0";
+        this.count = 1;
+    }
+
+    public History(int id, String phone, String ani, String dnis, String name, String date, String direction, String code, String duration, String calltype, String callhandle, String check, String view) {
+        this._id = id;
+        this.phone = phone;
+        this.ani = ani;
+        this.dnis = dnis;
+        this.name = name;
+        this.date = date;
+        this.direction = direction;
+        this.code = code;
+        this.duration = duration;
+        this.calltype = calltype;
+        this.callhandle = callhandle;
+        this.check = check;
+        this.view = view;
+        this.count = 1;
+    }
+}

+ 95 - 0
WallPadCall/src/main/java/bssoft/stack/sip/RFC2833.java

@@ -0,0 +1,95 @@
+package bssoft.stack.sip;
+
+public class RFC2833 {
+    public boolean bStart = false;
+
+    public boolean bEnd = false;
+
+    public static int payloadType = 101;
+
+    public int event = 0;
+
+    public int volume = 0;
+
+    public int reserved = 0;
+
+    public int edge = 0;
+
+    public int duration = 0;
+
+    public int exceedDuration = 0;
+
+    public boolean bActive;
+
+    public boolean flag;
+
+    public byte[] rfcdata = new byte[4];
+
+    public RFC2833() {
+        this.bActive = false;
+        this.flag = true;
+    }
+
+    public boolean setDtmf(int event, int volume, int reserved, int duration) {
+        System.out.println("DTMF SET :" + event + ":" + volume + ":" + reserved + ":" + duration);
+        this.bStart = true;
+        this.bEnd = false;
+        this.event = event;
+        this.volume = volume;
+        this.reserved = reserved;
+        this.edge = 0;
+        this.duration = duration;
+        this.bActive = true;
+        return true;
+    }
+
+    public boolean resetDtmf() {
+        this.bStart = false;
+        this.bEnd = false;
+        this.event = 0;
+        this.volume = 0;
+        this.reserved = 0;
+        this.edge = 0;
+        this.duration = 0;
+        this.exceedDuration = 0;
+        this.bActive = false;
+        return true;
+    }
+
+    public byte[] constructDtmfPacket() {
+        int field = 0;
+        field = this.event;
+        this.rfcdata[0] = (byte)(field << 24 >> 24);
+        field = 0;
+        field = this.volume << 26 >> 26 & 0x3F;
+        field |= this.edge << 31 >> 24 & 0x80;
+        this.rfcdata[1] = (byte)(field << 24 >> 24);
+        field = this.duration;
+        this.rfcdata[2] = (byte)(field << 16 >> 24);
+        this.rfcdata[3] = (byte)(field << 24 >> 24);
+        return this.rfcdata;
+    }
+
+    public byte[] constructDtmfPacket(int consumeduration) {
+        if (this.exceedDuration >= this.duration)
+            return null;
+        if (this.exceedDuration > 0)
+            this.bStart = false;
+        this.exceedDuration += consumeduration;
+        if (this.exceedDuration >= this.duration) {
+            this.edge = 1;
+            this.bEnd = true;
+        }
+        int field = 0;
+        field = this.event;
+        this.rfcdata[0] = (byte)(field << 24 >> 24);
+        field = 0;
+        field = this.volume << 26 >> 26 & 0x3F;
+        field |= this.edge << 31 >> 24 & 0x80;
+        this.rfcdata[1] = (byte)(field << 24 >> 24);
+        field = this.duration;
+        this.rfcdata[2] = (byte)(field << 16 >> 24);
+        this.rfcdata[3] = (byte)(field << 24 >> 24);
+        return this.rfcdata;
+    }
+}

+ 328 - 0
WallPadCall/src/main/java/bssoft/stack/sip/RTPCore.java

@@ -0,0 +1,328 @@
+package bssoft.stack.sip;
+
+import java.net.DatagramPacket;
+import java.util.Date;
+
+public class RTPCore {
+    public int RTP_PORT = 0;
+
+    public int mediaType = SIPStack.SIP_MEDIATYPE_NONE;
+
+    public byte[] buffer = null;
+
+    public byte[] pcmLinearBuffer = null;
+
+    public boolean bRTPlooping = false;
+
+    public boolean bRTPparsing = false;
+
+    public boolean bActive = false;
+
+    public int RTPversion = 0;
+
+    public int RTPpadding = 0;
+
+    public int RTPextension = 0;
+
+    public int RTPcsrc = 0;
+
+    public int RTPmark = 0;
+
+    public int RTPpayload = 0;
+
+    public int RTPsequence = 0;
+
+    public int RTPtimestamp = 0;
+
+    public int RTPssrc = 0;
+
+    public byte[] rtpPacketBuffer = null;
+
+    public byte[] rtpBulkBuffer = null;
+
+    public byte[] fieldBytes = null;
+
+    public byte[] rtpfieldBytes = null;
+
+    public boolean running = false;
+
+    public int remotePayloadType = SIPStack.SIP_CODEC_NONE;
+
+    public String remoteMediaIp = null;
+
+    public int remoteMediaPort = 0;
+
+    public boolean bDtmfDetected = false;
+
+    public int detectedDtmf = 0;
+
+    public Date rtpArrivalTime = null;
+
+    public int packetSize = 0;
+
+    public int PARSEversion = 0;
+
+    public int PARSEpadding = 0;
+
+    public int PARSEextension = 0;
+
+    public int PARSEcsrc = 0;
+
+    public int PARSEmark = 0;
+
+    public int PARSEpayload = 0;
+
+    public int PARSEsequence = 0;
+
+    public int PARSEtimestamp = 0;
+
+    public int PARSEssrc = 0;
+
+    public int PARSERFCdtmf = 0;
+
+    public int PARSERFCedge = 0;
+
+    public int PARSERFCvolume = 0;
+
+    public int PARSERFCduration = 0;
+
+    public RTPCore(int port, int mediaType) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        this.RTP_PORT = port;
+        this.pcmLinearBuffer = new byte[1024];
+        this.rtpPacketBuffer = new byte[512];
+        this.rtpBulkBuffer = new byte[512];
+        this.fieldBytes = new byte[4];
+        this.rtpfieldBytes = new byte[4];
+        this.RTPversion = 2;
+        this.RTPpadding = 0;
+        this.RTPextension = 0;
+        this.RTPcsrc = 0;
+        this.RTPmark = 0;
+        this.RTPpayload = 0;
+        this.RTPsequence = 0;
+        Date date = new Date();
+        this.RTPtimestamp = (int)date.getTime();
+        this.RTPssrc = (int)date.getTime();
+        this.mediaType = mediaType;
+        if (mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            this.buffer = new byte[SIPStack.RTP_AUDIO_SIZE];
+        } else if (mediaType == SIPStack.SIP_MEDIATYPE_VIDEO) {
+            this.buffer = new byte[65507];
+        } else {
+            this.buffer = new byte[65507];
+        }
+        this.bActive = false;
+        this.bDtmfDetected = false;
+        this.detectedDtmf = 0;
+        this.rtpArrivalTime = new Date();
+    }
+
+    public boolean encodeRtpHeader(byte[] header, int version, int padding, int extension, int csrc, int mark, int payload, int sequence, int timestamp, int ssrc) {
+        if (header == null || header.length < 12)
+            return false;
+        int iField = 0;
+        int iAppend = 0;
+        iField = version << 6 & 0xC0;
+        iAppend = padding << 5 & 0x20;
+        iField |= iAppend;
+        iAppend = extension << 4 & 0x10;
+        iField |= iAppend;
+        iAppend = csrc & 0xF;
+        iField |= iAppend;
+        header[0] = (byte)iField;
+        iField = 0;
+        iField = mark << 7 & 0x80;
+        iAppend = payload & 0x7F;
+        iField |= iAppend;
+        header[1] = (byte)iField;
+        iField = 0;
+        header[2] = (byte)(sequence << 16 >> 24);
+        header[3] = (byte)(sequence << 24 >> 24);
+        header[4] = (byte)(timestamp >> 24);
+        header[5] = (byte)(timestamp << 8 >> 24);
+        header[6] = (byte)(timestamp << 16 >> 24);
+        header[7] = (byte)(timestamp << 24 >> 24);
+        header[8] = (byte)(ssrc >> 24);
+        header[9] = (byte)(ssrc << 8 >> 24);
+        header[10] = (byte)(ssrc << 16 >> 24);
+        header[11] = (byte)(ssrc << 24 >> 24);
+        return true;
+    }
+
+    public boolean encodeRtpHeader(int payload) {
+        if (this.rtpPacketBuffer == null || this.rtpPacketBuffer.length < 12)
+            return false;
+        int iField = 0;
+        int iAppend = 0;
+        iField = this.RTPversion << 6 & 0xC0;
+        iAppend = this.RTPpadding << 5 & 0x20;
+        iField |= iAppend;
+        iAppend = this.RTPextension << 4 & 0x10;
+        iField |= iAppend;
+        iAppend = this.RTPcsrc & 0xF;
+        iField |= iAppend;
+        this.rtpPacketBuffer[0] = (byte)iField;
+        iField = 0;
+        iField = this.RTPmark << 7 & 0x80;
+        iAppend = payload & 0x7F;
+        iField |= iAppend;
+        this.rtpPacketBuffer[1] = (byte)iField;
+        iField = 0;
+        this.rtpPacketBuffer[2] = (byte)(this.RTPsequence << 16 >> 24);
+        this.rtpPacketBuffer[3] = (byte)(this.RTPsequence << 24 >> 24);
+        this.rtpPacketBuffer[4] = (byte)(this.RTPtimestamp >> 24);
+        this.rtpPacketBuffer[5] = (byte)(this.RTPtimestamp << 8 >> 24);
+        this.rtpPacketBuffer[6] = (byte)(this.RTPtimestamp << 16 >> 24);
+        this.rtpPacketBuffer[7] = (byte)(this.RTPtimestamp << 24 >> 24);
+        this.rtpPacketBuffer[8] = (byte)(this.RTPssrc >> 24);
+        this.rtpPacketBuffer[9] = (byte)(this.RTPssrc << 8 >> 24);
+        this.rtpPacketBuffer[10] = (byte)(this.RTPssrc << 16 >> 24);
+        this.rtpPacketBuffer[11] = (byte)(this.RTPssrc << 24 >> 24);
+        return true;
+    }
+
+    public int getBytesToInt(byte[] bytes) {
+        int newValue = 0;
+        newValue |= bytes[0] << 24 & 0xFF000000;
+        newValue |= bytes[1] << 16 & 0xFF0000;
+        newValue |= bytes[2] << 8 & 0xFF00;
+        newValue |= bytes[3] & 0xFF;
+        return newValue;
+    }
+
+    public byte[] getIntToBytes(int iValue) {
+        byte[] newbytes = new byte[4];
+        newbytes[0] = (byte)(iValue >> 24);
+        newbytes[1] = (byte)(iValue << 8 >> 24);
+        newbytes[2] = (byte)(iValue << 16 >> 24);
+        newbytes[3] = (byte)(iValue << 24 >> 24);
+        return newbytes;
+    }
+
+    public boolean setRTPPort(int port) {
+        if (port <= 0)
+            return false;
+        this.RTP_PORT = port;
+        return true;
+    }
+
+    public void setRemoteMediaInfo(int payloadtype, String mediaIp, int mediaPort) {
+        this.remotePayloadType = payloadtype;
+        this.remoteMediaIp = mediaIp;
+        this.remoteMediaPort = mediaPort;
+    }
+
+    public void parseRtpHeader(byte[] buffer) {
+        if (buffer == null || buffer.length < 12)
+            return;
+        this.fieldBytes[0] = buffer[0];
+        int version = this.fieldBytes[0] >> 6 & 0x3;
+        System.out.println("VERSION:" + version);
+        this.fieldBytes[0] = buffer[1];
+        int payloadType = this.fieldBytes[0] & Byte.MAX_VALUE;
+        System.out.println("Payload:" + payloadType);
+        this.fieldBytes[0] = 0;
+        this.fieldBytes[1] = 0;
+        this.fieldBytes[2] = buffer[2];
+        this.fieldBytes[3] = buffer[3];
+        int sequencNumber = getBytesToInt(this.fieldBytes);
+        System.out.println("SEQUENCE NUMBER:" + sequencNumber);
+        this.fieldBytes[0] = buffer[4];
+        this.fieldBytes[1] = buffer[5];
+        this.fieldBytes[2] = buffer[6];
+        this.fieldBytes[3] = buffer[7];
+        int timeStamp = getBytesToInt(this.fieldBytes);
+        System.out.println("TIMESTAMP:" + timeStamp);
+        this.fieldBytes[0] = buffer[8];
+        this.fieldBytes[1] = buffer[9];
+        this.fieldBytes[2] = buffer[10];
+        this.fieldBytes[3] = buffer[11];
+        int ssrc = getBytesToInt(this.fieldBytes);
+        System.out.println("SSRC:" + ssrc);
+    }
+
+    public void init() {
+        this.RTPversion = 2;
+        this.RTPpadding = 0;
+        this.RTPextension = 0;
+        this.RTPcsrc = 0;
+        this.RTPmark = 0;
+        this.RTPpayload = 0;
+        this.RTPsequence = 0;
+        Date date = new Date();
+        this.RTPtimestamp = (int)date.getTime();
+        this.RTPssrc = (int)date.getTime();
+        this.bDtmfDetected = false;
+        this.detectedDtmf = 0;
+        this.bActive = false;
+        this.rtpArrivalTime = new Date();
+    }
+
+    public boolean parseRTPHeader() {
+        try {
+            this.PARSEversion = 0;
+            this.PARSEpadding = 0;
+            this.PARSEextension = 0;
+            this.PARSEcsrc = 0;
+            this.PARSEmark = 0;
+            this.PARSEpayload = 0;
+            this.PARSEsequence = 0;
+            this.PARSEtimestamp = 0;
+            this.PARSEssrc = 0;
+            this.rtpfieldBytes[0] = this.buffer[1];
+            this.PARSEmark = this.rtpfieldBytes[0] >> 7 & 0x1;
+            this.PARSEpayload = this.rtpfieldBytes[0] & Byte.MAX_VALUE;
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    public String getRemotAddress(DatagramPacket dp) {
+        String strIp = "0.0.0.0:0";
+        try {
+            byte[] address = dp.getAddress().getAddress();
+            if (address.length == 4) {
+                int unsignedByte1 = (address[0] < 0) ? (address[0] + 256) : address[0];
+                int unsignedByte2 = (address[1] < 0) ? (address[1] + 256) : address[1];
+                int unsignedByte3 = (address[2] < 0) ? (address[2] + 256) : address[2];
+                int unsignedByte4 = (address[3] < 0) ? (address[3] + 256) : address[3];
+                strIp = String.valueOf(unsignedByte1) + "." + unsignedByte2 + "." + unsignedByte3 + "." + unsignedByte4 + ":" + dp.getPort();
+            }
+        } catch (Exception exception) {}
+        return strIp;
+    }
+
+    public boolean parseRFC2833() {
+        this.PARSERFCdtmf = 0;
+        this.PARSERFCedge = 0;
+        this.PARSERFCvolume = 0;
+        this.PARSERFCduration = 0;
+        try {
+            int field = 0;
+            this.PARSERFCdtmf = this.buffer[12];
+            field = this.buffer[13];
+            this.PARSERFCedge = (field & 0x80) >> 7;
+            this.PARSERFCvolume = field & 0x3F;
+            this.PARSERFCduration = this.buffer[14] << 24 >> 16 & 0xFF00;
+            this.PARSERFCduration |= this.buffer[15] << 24 >> 24 & 0xFF;
+            return true;
+        } catch (Exception exception) {
+            return false;
+        }
+    }
+
+    public String getVideomediadescription() {
+        int port = this.RTP_PORT + 2;
+        String str = "m=video " + port + " RTP/AVP " + SIPStack.SIP_CODEC_H264 + SIPStack.SIP_LINE_END +
+                "a=rtpmap:" + SIPStack.SIP_CODEC_H264 + " H264/90000" + SIPStack.SIP_LINE_END +
+                "a=fmtp:" + SIPStack.SIP_CODEC_H264 + " packetization-mode=1;profile-level-id=2" + SIPStack.SIP_LINE_END +
+                "a=cliprect:0,0,240,320" + SIPStack.SIP_LINE_END +
+                "a=framesize:" + SIPStack.SIP_CODEC_H264 + " 320-240" + SIPStack.SIP_LINE_END;
+        return str;
+    }
+}

+ 316 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SDPMedia.java

@@ -0,0 +1,316 @@
+package bssoft.stack.sip;
+
+import java.util.StringTokenizer;
+
+public class SDPMedia {
+    public int mediaType = SIPStack.SIP_MEDIATYPE_NONE;
+
+    public String mediaIp = null;
+
+    public int mediaPort = 0;
+
+    public int flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE;
+
+    public StringBuffer rtpmapBuffer = null;
+
+    public StringBuffer fmtpBuffer = null;
+
+    public String flow = "sendrecv";
+
+    public StringBuffer codecS = null;
+
+    public int commonCodec = -1;
+
+    public boolean flag = false;
+
+    public String mediaString = null;
+
+    public SDPMedia(int mediatype) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        this.mediaType = mediatype;
+        this.mediaIp = null;
+        this.mediaPort = 0;
+        this.rtpmapBuffer = new StringBuffer();
+        this.fmtpBuffer = new StringBuffer();
+        this.flow = "sendrecv";
+        this.codecS = new StringBuffer();
+        this.commonCodec = -1;
+        this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
+        this.flag = true;
+    }
+
+    public SDPMedia(String mediadescribe, String platformIp) {
+        this.mediaType = SIPStack.SIP_MEDIATYPE_NONE;
+        this.mediaIp = platformIp;
+        this.mediaPort = 0;
+        this.rtpmapBuffer = new StringBuffer();
+        this.fmtpBuffer = new StringBuffer();
+        this.flow = "sendrecv";
+        this.codecS = new StringBuffer();
+        this.commonCodec = -1;
+        this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
+        boolean bContinueParse = true;
+        if (mediadescribe != null && mediadescribe.length() > 0) {
+            int iS = 0;
+            int iE = 0;
+            String header = null;
+            if (mediadescribe.startsWith("m=audio ")) {
+                this.mediaType = SIPStack.SIP_MEDIATYPE_AUDIO;
+            } else if (mediadescribe.startsWith("m=video ")) {
+                this.mediaType = SIPStack.SIP_MEDIATYPE_VIDEO;
+            } else {
+                bContinueParse = false;
+            }
+            if (bContinueParse) {
+                iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END);
+                if (iE > 0) {
+                    header = mediadescribe.substring(0, iE);
+                    StringTokenizer st = new StringTokenizer(header, " ", true);
+                    int fieldCount = 0;
+                    while (st.hasMoreTokens()) {
+                        String str = st.nextToken().trim();
+                        if (str.length() > 0 && str.compareTo(" ") != 0) {
+                            if (fieldCount == 0) {
+                                if (str.compareTo("m=audio") != 0) {
+                                    bContinueParse = false;
+                                    break;
+                                }
+                            } else if (fieldCount == 1) {
+                                this.mediaPort = Integer.parseInt(str);
+                            } else if (fieldCount == 2) {
+                                if (str.compareTo("RTP/AVP") != 0) {
+                                    bContinueParse = false;
+                                    break;
+                                }
+                            } else if (fieldCount > 2) {
+                                if (this.codecS.length() > 0) {
+                                    this.codecS.append(" " + str);
+                                } else {
+                                    this.codecS.append(str);
+                                }
+                            }
+                            fieldCount++;
+                        }
+                    }
+                } else {
+                    bContinueParse = false;
+                }
+            }
+            if (bContinueParse) {
+                StringTokenizer st = new StringTokenizer(mediadescribe, "\n", true);
+                while (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    if (str.length() > 0 && str.startsWith("a=")) {
+                        if (str.startsWith("a=rtpmap:")) {
+                            this.rtpmapBuffer.append(String.valueOf(str) + "\n");
+                            continue;
+                        }
+                        if (str.startsWith("a=fmtp:")) {
+                            this.fmtpBuffer.append(String.valueOf(str) + "\n");
+                            continue;
+                        }
+                        if (str.startsWith("a=sendrecv")) {
+                            this.flow = "sendrecv";
+                            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
+                            continue;
+                        }
+                        if (str.startsWith("a=sendonly")) {
+                            this.flow = "sendonly";
+                            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY;
+                            continue;
+                        }
+                        if (str.startsWith("a=recvonly")) {
+                            this.flow = "recvonly";
+                            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY;
+                        }
+                    }
+                }
+            }
+            if (bContinueParse && mediadescribe.indexOf("\nc=IN IP4 ") > 0) {
+                iS = 0;
+                iE = 0;
+                iS = mediadescribe.indexOf("c=");
+                if (iS >= 0) {
+                    iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END, iS);
+                    header = "";
+                    if (iS >= 0 && iE > iS) {
+                        header = mediadescribe.substring(iS, iE + 2);
+                        iE = header.indexOf(SIPStack.SIP_LINE_END);
+                        this.mediaIp = header.substring("c=IN IP4 ".length(), iE);
+                    }
+                }
+            }
+        }
+        if (!bContinueParse)
+            resetMedia();
+        this.flag = true;
+    }
+
+    public void resetMedia() {
+        this.mediaType = SIPStack.SIP_MEDIATYPE_NONE;
+        this.mediaIp = null;
+        this.mediaPort = 0;
+        this.rtpmapBuffer = null;
+        this.fmtpBuffer = null;
+        this.flow = "sendrecv";
+        this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
+        this.codecS = null;
+        this.commonCodec = -1;
+        this.flag = false;
+        this.mediaString = null;
+    }
+
+    public String getMediaString() {
+        if (!this.flag)
+            return null;
+        String mString = "";
+        String aString = "";
+        String fmtpString = "";
+        String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END;
+        if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.codecS.toString() + SIPStack.SIP_LINE_END;
+        } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) {
+            return null;
+        }
+        if (this.rtpmapBuffer.length() > 0)
+            aString = this.rtpmapBuffer.toString();
+        if (this.fmtpBuffer.length() > 0)
+            fmtpString = this.fmtpBuffer.toString();
+        this.mediaString = String.valueOf(mString) +
+                aString +
+                fmtpString +
+                flowString;
+        return this.mediaString;
+    }
+
+    public String getFinalMediaString() {
+        if (!this.flag)
+            return null;
+        if (this.commonCodec < 0)
+            return null;
+        String mString = "";
+        String aString = "";
+        String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END;
+        if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.commonCodec + SIPStack.SIP_LINE_END;
+        } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) {
+            return null;
+        }
+        if (this.commonCodec == 0) {
+            aString = "a=rtpmap:0 PCMU/8000" + SIPStack.SIP_LINE_END;
+        } else if (this.commonCodec == 8) {
+            aString = "a=rtpmap:8 PCMA/8000" + SIPStack.SIP_LINE_END;
+        } else if (this.commonCodec == 18) {
+            aString = "a=rtpmap:18 G729/8000" + SIPStack.SIP_LINE_END;
+        }
+        this.mediaString = String.valueOf(mString) +
+                aString +
+                flowString;
+        return this.mediaString;
+    }
+
+    public boolean setMediaAddress(String ip, int port) {
+        if (!this.flag)
+            return false;
+        if (port < 0 || port > 65556)
+            return false;
+        this.mediaIp = ip;
+        this.mediaPort = port;
+        return true;
+    }
+
+    public boolean setCodec(int codec) {
+        if (!this.flag)
+            return false;
+        if (this.codecS.length() > 0) {
+            this.codecS.append(" " + codec);
+        } else {
+            this.codecS.append(codec);
+        }
+        return true;
+    }
+
+    public boolean setCodec(int codec, String describe) {
+        if (!this.flag)
+            return false;
+        setCodec(codec);
+        this.rtpmapBuffer.append("a=rtpmap:" + codec + " " + describe + SIPStack.SIP_LINE_END);
+        return true;
+    }
+
+    public boolean setFmtpDescribe(int codec, String describe) {
+        if (!this.flag)
+            return false;
+        this.fmtpBuffer.append("a=fmtp:" + codec + " " + describe + SIPStack.SIP_LINE_END);
+        return true;
+    }
+
+    public boolean setCommonCodec(int codec) {
+        if (!this.flag)
+            return false;
+        this.commonCodec = codec;
+        return true;
+    }
+
+    public boolean setFlow(String flow) {
+        if (flow == null)
+            return false;
+        if (!this.flag)
+            return false;
+        this.flow = flow;
+        if (flow.compareTo("sendrecv") == 0) {
+            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
+        } else if (flow.compareTo("sendonly") == 0) {
+            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY;
+        } else if (flow.compareTo("recvonly") == 0) {
+            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY;
+        } else {
+            this.flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE;
+        }
+        return true;
+    }
+
+    public int negotiateAudioCodec(String sideCodecs) {
+        if (this.codecS == null || this.codecS.length() <= 0)
+            return -1;
+        String myCodecs = this.codecS.toString();
+        myCodecs.trim();
+        if (myCodecs == null || myCodecs.length() <= 0)
+            return -1;
+        sideCodecs.trim();
+        if (sideCodecs == null || sideCodecs.length() <= 0)
+            return -1;
+        StringTokenizer my_st = new StringTokenizer(myCodecs, " ", true);
+        String str = null;
+        int codec = -1;
+        while (my_st.hasMoreTokens()) {
+            str = my_st.nextToken().trim();
+            if (str == null || str.length() == 0)
+                continue;
+            codec = Integer.parseInt(str);
+            if (codec >= 0 && codec < 100) {
+                StringTokenizer side_st = new StringTokenizer(sideCodecs, " ", true);
+                int sidecodec = -1;
+                boolean bDecided = false;
+                while (side_st.hasMoreTokens()) {
+                    str = side_st.nextToken().trim();
+                    if (str == null || str.length() == 0)
+                        continue;
+                    sidecodec = Integer.parseInt(str);
+                    if (str.length() > 0 && sidecodec >= 0 && codec < 100)
+                        if (sidecodec == codec) {
+                            bDecided = true;
+                            this.commonCodec = codec;
+                            break;
+                        }
+                }
+                if (bDecided)
+                    return this.commonCodec;
+            }
+        }
+        return -1;
+    }
+}

+ 138 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPAUTHENTICATEHeader.java

@@ -0,0 +1,138 @@
+package bssoft.stack.sip;
+
+public class SIPAUTHENTICATEHeader {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public String realmValue = null;
+
+    public String nonceValue = null;
+
+    public String qopValue = null;
+
+    public String strStale = null;
+
+    public String strAlgorithm = null;
+
+    public int headerType = SIPStack.SIP_HEADERTYPE_NONE;
+
+    public boolean flag = false;
+
+    public SIPAUTHENTICATEHeader(String header, int headerType) {
+        if (header != null) {
+            String keyWord;
+            if (headerType == SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE) {
+                keyWord = "WWW-Authenticate: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE) {
+                keyWord = "Www-Authenticate: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE) {
+                keyWord = "Proxy-Authenticate: ";
+            } else {
+                keyWord = null;
+            }
+            if (keyWord != null)
+                if (header.startsWith(keyWord)) {
+                    this.headerType = headerType;
+                    this.header = header;
+                    this.flag = true;
+                    int iS = 0;
+                    int iE = 0;
+                    String strRealm = null;
+                    iS = header.indexOf("realm=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = header.indexOf(",", iS);
+                        if (iE > 0) {
+                            strRealm = header.substring(iS, iE);
+                        } else if (iE < 0) {
+                            strRealm = header.substring(iS);
+                        }
+                        if (strRealm.length() > 0) {
+                            iS = strRealm.indexOf("=");
+                            String strValue = strRealm.substring(iS + 1);
+                            strValue = strValue.trim();
+                            if (strValue.indexOf("\"") == 0)
+                                iS = 1;
+                            if (iS > 0)
+                                iE = strValue.indexOf("\"", iS);
+                            this.realmValue = strValue.substring(iS, iE);
+                        }
+                    } else {
+                        this.realmValue = "";
+                    }
+                    String strQop = null;
+                    iS = header.indexOf("qop=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = header.indexOf(",", iS);
+                        if (iE > 0) {
+                            strQop = header.substring(iS, iE);
+                        } else if (iE < 0) {
+                            strQop = header.substring(iS);
+                        }
+                        this.qopValue = "";
+                        if (strQop.length() > 0) {
+                            iS = strQop.indexOf("=");
+                            String strValue = strQop.substring(iS + 1);
+                            strValue = strValue.trim();
+                            if (strValue.indexOf("\"") == 0)
+                                iS = 1;
+                            if (iS > 0)
+                                iE = strValue.indexOf("\"", iS);
+                            this.qopValue = strValue.substring(iS, iE);
+                        }
+                    } else {
+                        this.qopValue = "";
+                    }
+                    String strNonce = null;
+                    iS = header.indexOf("nonce=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = header.indexOf(",", iS);
+                        if (iE > 0) {
+                            strNonce = header.substring(iS, iE);
+                        } else if (iE < 0) {
+                            strNonce = header.substring(iS);
+                        }
+                        if (strNonce.length() > 0) {
+                            iS = strNonce.indexOf("=");
+                            String strValue = strNonce.substring(iS + 1);
+                            strValue = strValue.trim();
+                            if (strValue.indexOf("\"") == 0)
+                                iS = 1;
+                            if (iS > 0)
+                                iE = strValue.indexOf("\"", iS);
+                            this.nonceValue = strValue.substring(iS, iE);
+                        }
+                    } else {
+                        this.nonceValue = "";
+                    }
+                    iS = header.indexOf("stale=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = header.indexOf(",", iS);
+                        if (iE > 0) {
+                            this.strStale = header.substring(iS + 6, iE);
+                        } else if (iE < 0) {
+                            this.strStale = header.substring(iS + 6);
+                        }
+                    } else {
+                        this.strStale = "";
+                    }
+                    iS = header.indexOf("algorithm=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = header.indexOf(",", iS);
+                        if (iE > 0) {
+                            this.strAlgorithm = header.substring(iS + 10, iE);
+                        } else if (iE < 0) {
+                            this.strAlgorithm = header.substring(iS + 10);
+                        }
+                    } else {
+                        this.strAlgorithm = "";
+                    }
+                }
+        }
+    }
+}

+ 330 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPCONTACTHeader.java

@@ -0,0 +1,330 @@
+package bssoft.stack.sip;
+
+public class SIPCONTACTHeader {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public int expires = -1;
+
+    public String display = null;
+
+    public String username = null;
+
+    public String sipuri = null;
+
+    public String uriusertag = null;
+
+    public String ip = null;
+
+    public int port = 0;
+
+    public String tag = null;
+
+    public boolean flag = false;
+
+    public SIPCONTACTHeader(String message) {
+        if (message != null && message.length() > 0) {
+            int iS = message.indexOf("Contact: ");
+            int iE = 0;
+            if (iS < 0) {
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "m: ");
+                if (iS >= 0)
+                    iS += 2;
+            }
+            if (iS >= 0) {
+                iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                if (iE > 0) {
+                    this.header = message.substring(iS, iE);
+                    if (this.header.startsWith("Contact: ")) {
+                        this.headerValue = this.header.substring(9);
+                    } else if (this.header.startsWith("m: ")) {
+                        this.headerValue = this.header.substring(3);
+                    }
+                    String strExpires = null;
+                    iS = this.headerValue.indexOf(";expires=");
+                    iE = 0;
+                    if (iS >= 0) {
+                        iE = this.headerValue.indexOf(";", iS + 1);
+                        int iE_ = this.headerValue.indexOf(",", iS + 1);
+                        if (iE_ > 0 && iE_ < iE)
+                            iE = iE_;
+                        if (iE > 0) {
+                            strExpires = this.headerValue.substring(iS, iE);
+                        } else if (iE < 0) {
+                            strExpires = this.headerValue.substring(iS);
+                        }
+                        if (strExpires != null && strExpires.length() > 0)
+                            this.expires = Integer.parseInt(strExpires.substring(9).trim());
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            if (this.headerValue != null && this.headerValue.length() > 0) {
+                iE = this.headerValue.indexOf("<sip:");
+                if (iE > 0) {
+                    String str = null;
+                    str = this.headerValue.substring(0, iE).trim();
+                    if (str != null && str.length() > 1 &&
+                            str.startsWith("\"") &&
+                            str.endsWith("\"")) {
+                        this.display = str.substring(1, str.length() - 1);
+                    } else if (str != null && str.length() > 0) {
+                        this.display = str;
+                    }
+                }
+                iS = this.headerValue.indexOf("sip:");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(">", iS + 4);
+                    if (iE < 0)
+                        iE = this.headerValue.indexOf(";", iS + 4);
+                    if (iE > 0) {
+                        str = this.headerValue.substring(iS, iE);
+                    } else {
+                        str = this.headerValue.substring(iS);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.sipuri = str.trim();
+                }
+                if (this.sipuri != null && this.sipuri.length() > 0) {
+                    iS = this.sipuri.indexOf("@", 4);
+                    if (iS > 0)
+                        this.username = this.sipuri.substring(4, iS).trim();
+                }
+                if (this.sipuri != null && this.sipuri.length() > 0) {
+                    iS = this.sipuri.indexOf("@", 4);
+                    iE = this.sipuri.indexOf(";", 4);
+                    String str = null;
+                    if (iS >= 0 && iE >= 0) {
+                        str = this.sipuri.substring(iS + 1, iE).trim();
+                    } else if (iS >= 0) {
+                        str = this.sipuri.substring(iS + 1).trim();
+                    } else if (iE >= 0) {
+                        str = this.sipuri.substring(4, iE).trim();
+                    } else {
+                        str = this.sipuri.substring(4).trim();
+                    }
+                    this.port = 5060;
+                    if (str != null && str.length() > 0) {
+                        iS = str.indexOf(":");
+                        if (iS > 0) {
+                            this.port = Integer.parseInt(str.substring(iS + 1).trim());
+                            this.ip = str.substring(0, iS);
+                        } else {
+                            this.ip = str;
+                        }
+                    }
+                }
+                iS = this.headerValue.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.headerValue.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.headerValue.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.tag = str.trim();
+                }
+                iS = this.headerValue.indexOf("sip:");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(">", iS + 4);
+                    if (iE > 0)
+                        str = this.headerValue.substring(iS, iE);
+                    if (str != null && str.length() > 0) {
+                        iS = str.indexOf(";user=", iS + 4);
+                        if (iS > 0) {
+                            this.uriusertag = str.substring(iS + 6);
+                            if (this.uriusertag != null && this.uriusertag.length() > 0 && this.uriusertag.indexOf(";") >= 0)
+                                if (this.uriusertag.indexOf(";") == 0) {
+                                    this.uriusertag = null;
+                                } else {
+                                    this.uriusertag = this.uriusertag.substring(0, this.uriusertag.indexOf(";")).trim();
+                                }
+                        }
+                    }
+                }
+                this.flag = true;
+            }
+        }
+    }
+
+    public SIPCONTACTHeader(String message, String requesturi) {
+        if (message != null && message.length() > 0) {
+            int iS = message.indexOf("Contact: ");
+            int iE = 0;
+            if (iS < 0) {
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "m: ");
+                if (iS >= 0)
+                    iS += 2;
+            }
+            if (iS >= 0) {
+                iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                if (iE > 0) {
+                    this.header = message.substring(iS, iE);
+                    if (this.header.startsWith("Contact: ")) {
+                        this.headerValue = this.header.substring(9);
+                    } else if (this.header.startsWith("m: ")) {
+                        this.headerValue = this.header.substring(3);
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            if (this.headerValue != null && this.headerValue.length() > 0) {
+                this.display = "";
+                String tempValue = this.headerValue;
+                iS = tempValue.indexOf("sip:");
+                String str = "";
+                boolean bFound = false;
+                while (iS >= 0) {
+                    tempValue = tempValue.substring(iS);
+                    iE = tempValue.indexOf(">", 4);
+                    if (iE < 0)
+                        iE = tempValue.indexOf(";", 4);
+                    if (iE > 0) {
+                        str = tempValue.substring(0, iE);
+                    } else {
+                        str = tempValue;
+                    }
+                    if (str != null && str.length() > 0)
+                        this.sipuri = str.trim();
+                    if (str != null &&
+                            str.length() > 0 &&
+                            requesturi != null &&
+                            requesturi.length() > 0 &&
+                            str.trim().compareTo(requesturi) == 0) {
+                        bFound = true;
+                        this.sipuri = str.trim();
+                        String strExpires = null;
+                        iS = tempValue.indexOf(";expires=");
+                        iE = 0;
+                        if (iS >= 0) {
+                            iE = tempValue.indexOf(";", iS + 1);
+                            int iE_ = tempValue.indexOf(",", iS + 1);
+                            if (iE_ > 0 && iE_ < iE)
+                                iE = iE_;
+                            if (iE > 0) {
+                                strExpires = tempValue.substring(iS, iE);
+                            } else if (iE < 0) {
+                                strExpires = tempValue.substring(iS);
+                            }
+                            if (strExpires != null && strExpires.length() > 0)
+                                this.expires = Integer.parseInt(strExpires.substring(9).trim());
+                        }
+                        break;
+                    }
+                    tempValue = tempValue.substring(iE + 1).trim();
+                    iS = tempValue.indexOf("sip:");
+                }
+                if (bFound) {
+                    if (this.sipuri != null && this.sipuri.length() > 0) {
+                        iS = this.sipuri.indexOf("@", 4);
+                        if (iS > 0)
+                            this.username = this.sipuri.substring(4, iS).trim();
+                    }
+                    if (this.sipuri != null && this.sipuri.length() > 0) {
+                        iS = this.sipuri.indexOf("@", 4);
+                        iE = this.sipuri.indexOf(";", 4);
+                        if (iS >= 0 && iE >= 0) {
+                            str = this.sipuri.substring(iS + 1, iE).trim();
+                        } else if (iS >= 0) {
+                            str = this.sipuri.substring(iS + 1).trim();
+                        } else if (iE >= 0) {
+                            str = this.sipuri.substring(4, iE).trim();
+                        } else {
+                            str = this.sipuri.substring(4).trim();
+                        }
+                        this.port = 5060;
+                        if (str != null && str.length() > 0) {
+                            iS = str.indexOf(":");
+                            if (iS > 0) {
+                                this.port = Integer.parseInt(str.substring(iS + 1).trim());
+                                this.ip = str.substring(0, iS);
+                            } else {
+                                this.ip = str;
+                            }
+                        }
+                    }
+                    iS = this.headerValue.indexOf(";tag=");
+                    if (iS > 0) {
+                        iE = this.headerValue.indexOf(";", iS + 5);
+                        if (iE >= 0) {
+                            if (iE > iS + 5) {
+                                str = this.headerValue.substring(iS + 5, iE);
+                            } else {
+                                str = "";
+                            }
+                        } else {
+                            str = this.headerValue.substring(iS + 5);
+                        }
+                        if (str != null && str.length() > 0) {
+                            this.tag = str.trim();
+                        } else {
+                            this.tag = "";
+                        }
+                    }
+                    iS = this.headerValue.indexOf("sip:");
+                    if (iS > 0) {
+                        iE = this.headerValue.indexOf(">", iS + 4);
+                        if (iE > 0)
+                            str = this.headerValue.substring(iS, iE);
+                        if (str != null && str.length() > 0) {
+                            iS = str.indexOf(";user=", iS + 4);
+                            if (iS > 0) {
+                                this.uriusertag = str.substring(iS + 6);
+                                if (this.uriusertag != null && this.uriusertag.length() > 0 && this.uriusertag.indexOf(";") >= 0)
+                                    if (this.uriusertag.indexOf(";") == 0) {
+                                        this.uriusertag = null;
+                                    } else {
+                                        this.uriusertag = this.uriusertag.substring(0, this.uriusertag.indexOf(";")).trim();
+                                    }
+                            }
+                        }
+                    }
+                    this.flag = true;
+                }
+            }
+        }
+    }
+
+    public String getDisplay() {
+        return this.display;
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    public String getSipuri() {
+        return this.sipuri;
+    }
+
+    public String getSipuriusertag() {
+        return this.uriusertag;
+    }
+
+    public String getIp() {
+        return this.ip;
+    }
+
+    public int getPort() {
+        return this.port;
+    }
+
+    public String getTag() {
+        return this.tag;
+    }
+
+    public int getExpires() {
+        return this.expires;
+    }
+}

+ 2511 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPCall.java

@@ -0,0 +1,2511 @@
+package bssoft.stack.sip;
+
+import java.util.Date;
+import java.util.StringTokenizer;
+
+public class SIPCall {
+    public String commandLine = null;
+
+    public String viaH = null;
+
+    public StringBuffer viaArray = new StringBuffer();
+
+    public String routeH = null;
+
+    public StringBuffer routeArray = new StringBuffer();
+
+    public String recordrouteH = null;
+
+    public StringBuffer recordrouteArray = new StringBuffer();
+
+    public String maxforwardH = null;
+
+    public String contactH = null;
+
+    public String toH = null;
+
+    public String fromH = null;
+
+    public String callidH = null;
+
+    public String cseqH = null;
+
+    public String expiresH = null;
+
+    public String allowH = null;
+
+    public String useragentH = null;
+
+    public String remoteuseragentH = null;
+
+    public String contentlengthH = null;
+
+    public String contenttypeH = null;
+
+    public String authorizationINVITEH = null;
+
+    public String authorizationCANCELH = null;
+
+    public String authorizationBYEH = null;
+
+    public String authorizationACKH = null;
+
+    public String passertedidentityH = null;
+
+    public String serverIp = null;
+
+    public int serverPort = 5060;
+
+    public String serverDomain = null;
+
+    public String remoteIp = null;
+
+    public int remotePort = 5060;
+
+    public String remoteContactIp = null;
+
+    public int remoteContactPort = 5060;
+
+    public String routeIp = null;
+
+    public int routePort = 5060;
+
+    public String remoteContactUri = null;
+
+    public String localIp = null;
+
+    public int localPort = 5060;
+
+    public String id = null;
+
+    public String cid = null;
+
+    public String authid = null;
+
+    public String authpassword = null;
+
+    public String fromTag = null;
+
+    public String toTag = null;
+
+    public String fromHeaderValue = null;
+
+    public String toHeaderValue = null;
+
+    public String callId = null;
+
+    public String dnis = null;
+
+    public String viaBranch = null;
+
+    public int CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+
+    public int INVITE_CSEQ = 0;
+
+    public int CANCEL_CSEQ = 0;
+
+    public int ACK_CSEQ = 0;
+
+    public int BYE_CSEQ = 0;
+
+    public int callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+
+    public int responseCode = 0;
+
+    public int callState = 0;
+
+    public int callMode = SIPStack.SIP_CALLMODE_NONE;
+
+    public Date callTime_TI = null;
+
+    public Date callTime_T0 = null;
+
+    public Date callTime_T00 = null;
+
+    public int invitingTimes = 0;
+
+    public Date callTime_T1 = null;
+
+    public Date callTime_T2 = null;
+
+    public Date callTime_T3 = null;
+
+    public Date callTime_T4 = null;
+
+    public Date callTime_T40 = null;
+
+    public Date callTime_T5 = null;
+
+    public Date callTime_T6 = null;
+
+    public Date callTime_T7 = null;
+
+    public Date callTime_T8 = null;
+
+    public Date callTime_T9 = null;
+
+    public int expiresTI = 0;
+
+    public int expiresT0 = 0;
+
+    public int expiresT00 = 0;
+
+    public int expiresT1 = 0;
+
+    public int expiresT2 = 0;
+
+    public int expiresT3 = 0;
+
+    public int expiresT4 = 0;
+
+    public int expiresT5 = 0;
+
+    public int expiresT6 = 0;
+
+    public int expiresT7 = 0;
+
+    public int expiresT8 = 0;
+
+    public int expiresT9 = 0;
+
+    public SIPSdp sdp = null;
+
+    public SIPSdp remoteSdp = null;
+
+    public String message = null;
+
+    public boolean flag;
+
+    public UPDATEHeaders updateHeaders = null;
+
+    public boolean bHolding = false;
+
+    public boolean bPending = false;
+
+    public boolean bDtmfdetected = false;
+
+    public int detectedDtmf = 0;
+
+    public int dtmfDuration = 0;
+
+    public boolean bCancelRequest = false;
+
+    public boolean bRejectRequest = false;
+
+    public boolean bNewcallRequest = false;
+
+    public boolean bUpdateRequest = false;
+
+    public boolean bAsMaster = false;
+
+    public boolean bForwardRequest = false;
+
+    public boolean bByedisconnected = false;
+
+    public String number = "";
+
+    public String dong_number = "";
+
+    public String ho_number = "";
+
+    public boolean bDirectcall = false;
+
+    public boolean bResponsebackgroundcall = false;
+
+    public boolean bResponsebackgroundcallReady = false;
+
+    public Date responsebackgroundcallTimer = new Date();
+
+    public int hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+
+    public int hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+
+    public SIPCall() {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("call handle created.");
+        this.updateHeaders = new UPDATEHeaders();
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_BASIC;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.bHolding = false;
+        this.bPending = false;
+        this.bCancelRequest = false;
+        this.bRejectRequest = false;
+        this.bNewcallRequest = false;
+        this.bUpdateRequest = false;
+        this.bAsMaster = false;
+        this.bForwardRequest = false;
+        this.bByedisconnected = false;
+        this.number = "";
+        this.viaBranch = null;
+        this.bResponsebackgroundcall = false;
+        this.bResponsebackgroundcallReady = false;
+        this.responsebackgroundcallTimer = new Date();
+        this.callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+        this.bDirectcall = SIPStack.bDirectCall;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+        this.flag = false;
+    }
+
+    public SIPCall(boolean bPending) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("call handle created.");
+        this.updateHeaders = new UPDATEHeaders();
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_BASIC;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.bHolding = false;
+        this.bCancelRequest = false;
+        this.bRejectRequest = false;
+        this.bNewcallRequest = false;
+        this.bUpdateRequest = false;
+        this.bAsMaster = false;
+        this.bForwardRequest = false;
+        this.bByedisconnected = false;
+        this.bResponsebackgroundcall = false;
+        this.bResponsebackgroundcallReady = false;
+        this.responsebackgroundcallTimer = new Date();
+        this.number = "";
+        this.viaBranch = null;
+        bPending = bPending;
+        this.bDirectcall = SIPStack.bDirectCall;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+        this.flag = false;
+    }
+
+    public void resetCall() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG) {
+            System.out.println("call handle reset.");
+            SIPStack.printAudioRtpPortInfo();
+        }
+        this.commandLine = null;
+        this.viaH = null;
+        this.viaArray = null;
+        this.routeH = null;
+        this.routeArray = null;
+        this.recordrouteH = null;
+        this.recordrouteArray = null;
+        this.maxforwardH = null;
+        this.contactH = null;
+        this.toH = null;
+        this.fromH = null;
+        this.callidH = null;
+        this.cseqH = null;
+        this.expiresH = null;
+        this.allowH = null;
+        this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+        this.remoteuseragentH = null;
+        this.contentlengthH = null;
+        this.contenttypeH = null;
+        this.authorizationINVITEH = null;
+        this.authorizationCANCELH = null;
+        this.authorizationBYEH = null;
+        this.authorizationACKH = null;
+        this.passertedidentityH = null;
+        this.serverIp = null;
+        this.serverPort = 5060;
+        this.serverDomain = null;
+        this.remoteIp = null;
+        this.remotePort = 5060;
+        this.remoteContactIp = null;
+        this.remoteContactPort = 5060;
+        this.remoteContactUri = null;
+        this.localIp = null;
+        this.localPort = 5060;
+        this.id = null;
+        this.cid = null;
+        this.authid = null;
+        this.authpassword = null;
+        this.fromTag = null;
+        this.toTag = null;
+        this.fromHeaderValue = null;
+        this.toHeaderValue = null;
+        this.callId = null;
+        this.dnis = null;
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_BASIC;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        if (this.sdp != null && this.sdp.flag && this.sdp.audioM != null)
+            SIPStack.freeAudioRtpPort(this.sdp.audioM.mediaPort);
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.message = null;
+        this.bHolding = false;
+        this.bPending = false;
+        this.bCancelRequest = false;
+        this.bRejectRequest = false;
+        this.bNewcallRequest = false;
+        this.bUpdateRequest = false;
+        this.bAsMaster = false;
+        this.bForwardRequest = false;
+        this.bByedisconnected = false;
+        this.bResponsebackgroundcall = false;
+        this.bResponsebackgroundcallReady = false;
+        this.responsebackgroundcallTimer = new Date();
+        this.number = "";
+        this.viaBranch = null;
+        this.callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+        this.bDirectcall = SIPStack.bDirectCall;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+        this.flag = false;
+        SIPStack.exceptionCountAtCurrentCall = 0;
+        System.gc();
+    }
+
+    public void initializeRedirectCall() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("redirect call handle initialize.");
+        this.viaH = null;
+        this.viaArray = null;
+        this.routeH = null;
+        this.routeArray = null;
+        this.recordrouteH = null;
+        this.recordrouteArray = null;
+        this.remoteContactIp = null;
+        this.remoteContactPort = 5060;
+        this.remoteContactUri = null;
+        this.callId = null;
+        this.authorizationINVITEH = null;
+        this.authorizationCANCELH = null;
+        this.authorizationBYEH = null;
+        this.authorizationACKH = null;
+        this.viaBranch = null;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_BASIC;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        if (this.sdp != null && this.sdp.flag && this.sdp.audioM != null)
+            SIPStack.freeAudioRtpPort(this.sdp.audioM.mediaPort);
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.message = null;
+        this.bHolding = false;
+        this.bPending = false;
+        this.bCancelRequest = false;
+        this.bRejectRequest = false;
+        this.bNewcallRequest = false;
+        this.bUpdateRequest = false;
+        this.bAsMaster = false;
+        this.bForwardRequest = false;
+        this.bByedisconnected = false;
+        this.bResponsebackgroundcall = false;
+        this.bResponsebackgroundcallReady = false;
+        this.responsebackgroundcallTimer = new Date();
+        this.number = "";
+        this.viaBranch = null;
+        this.callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+        this.bDirectcall = SIPStack.bDirectCall;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+    }
+
+    public boolean activeCallHandle(String id, String cid, String authid, String authpassword, String number, String serverIp, int serverPort, String serverDomain, String localIp, int localPort) {
+        if (this.flag)
+            return false;
+        resetCall();
+        this.flag = true;
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("call handle activated.");
+        this.id = localIp;
+        this.cid = localIp;
+        this.authid = authid;
+        this.authpassword = authpassword;
+        this.dnis = number;
+        this.serverIp = serverIp;
+        this.serverPort = serverPort;
+        this.serverDomain = serverDomain;
+        this.remoteIp = serverIp;
+        this.remotePort = serverPort;
+        this.localIp = localIp;
+        this.localPort = localPort;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+        return true;
+    }
+
+    public boolean activePendingCallHandle(String id, String cid, String authid, String authpassword, String number, String serverIp, int serverPort, String serverDomain, String localIp, int localPort) {
+        if (this.flag)
+            return false;
+        resetCall();
+        this.flag = true;
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("conference call activated.");
+        this.id = id;
+        this.cid = cid;
+        this.authid = authid;
+        this.authpassword = authpassword;
+        this.dnis = number;
+        this.serverIp = serverIp;
+        this.serverPort = serverPort;
+        this.serverDomain = serverDomain;
+        this.remoteIp = serverIp;
+        this.remotePort = serverPort;
+        this.localIp = localIp;
+        this.localPort = localPort;
+        this.bPending = true;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+        BSSVideo.bProgressvideooffer = false;
+        BSSVideo.bCover = true;
+        return true;
+    }
+
+    public boolean constructHeaders(String message, String remoteIp, int remotePort) {
+        if (message == null || message.length() == 0)
+            return false;
+        this.viaH = null;
+        this.viaArray = new StringBuffer();
+        this.routeH = null;
+        this.routeArray = new StringBuffer();
+        this.recordrouteH = null;
+        this.recordrouteArray = new StringBuffer();
+        this.message = message;
+        StringTokenizer tokenArray = new StringTokenizer(message, SIPStack.SIP_LINE_END, true);
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken().trim();
+            if (token.length() <= 0 ||
+                    token.compareTo("\r") == 0 ||
+                    token.compareTo("\n") == 0)
+                continue;
+            if (token.startsWith("From: ")) {
+                this.fromH = token;
+                this.fromHeaderValue = token.substring(6);
+                continue;
+            }
+            if (token.startsWith("f: ")) {
+                this.fromH = token;
+                this.fromHeaderValue = token.substring(3);
+                continue;
+            }
+            if (token.startsWith("To: ")) {
+                this.toH = token;
+                if (this.toH.indexOf("tag=") < 0) {
+                    this.toTag = Long.toString((new Date()).getTime());
+                    this.toH = String.valueOf(token) + ";tag=" + this.toTag;
+                    this.toHeaderValue = String.valueOf(token.substring(4)) + ";tag=" + this.toTag;
+                    continue;
+                }
+                this.toHeaderValue = token.substring(4);
+                continue;
+            }
+            if (token.startsWith("t: ")) {
+                this.toH = token;
+                if (this.toH.indexOf("tag=") < 0) {
+                    this.toTag = Long.toString((new Date()).getTime());
+                    this.toH = String.valueOf(token) + ";tag=" + this.toTag;
+                    this.toHeaderValue = String.valueOf(token.substring(3)) + ";tag=" + this.toTag;
+                    continue;
+                }
+                this.toHeaderValue = token.substring(3);
+                continue;
+            }
+            if (token.startsWith("Via: ")) {
+                if (this.viaH == null) {
+                    this.viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = "";
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            this.viaH = token.substring(0, index);
+                        } else {
+                            this.viaH = token;
+                        }
+                        index = this.viaH.indexOf(";rport=");
+                        if (index > 0)
+                            this.viaH = this.viaH.substring(0, index);
+                        this.viaH = String.valueOf(this.viaH) + ";received=" + remoteIp + ";rport=" + remotePort + ";branch=" + this.viaBranch;
+                    }
+                    this.viaArray.append(String.valueOf(this.viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("v: ")) {
+                if (this.viaH == null) {
+                    this.viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = branch;
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            this.viaH = token.substring(0, index);
+                        } else {
+                            this.viaH = token;
+                        }
+                        index = this.viaH.indexOf(";rport=");
+                        if (index > 0)
+                            this.viaH = this.viaH.substring(0, index);
+                        this.viaH = String.valueOf(this.viaH) + ";received=" + remoteIp + ";rport=" + remotePort + ";branch=" + this.viaBranch;
+                    }
+                    this.viaArray.append(String.valueOf(this.viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("Record-Route: ")) {
+                if (this.recordrouteH == null) {
+                    this.routeH = null;
+                    this.routeArray = new StringBuffer();
+                    this.recordrouteH = token;
+                    this.recordrouteArray.append(String.valueOf(this.recordrouteH) + SIPStack.SIP_LINE_END);
+                    this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.recordrouteArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("Contact: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("m: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("Call-ID: ")) {
+                this.callidH = token;
+                this.callId = token.substring(9).trim();
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_LOBBY)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_GUARD)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_LOBBY)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_NEIGHBOR)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = false;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+                this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                BSSVideo.bProgressvideooffer = false;
+                continue;
+            }
+            if (token.startsWith("i: ")) {
+                this.callidH = token;
+                this.callId = token.substring(3).trim();
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_LOBBY)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_GUARD)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_LOBBY)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_LOBBY;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                if (this.callId.startsWith(BSSVideo.HNS_PREFIX_NEIGHBOR)) {
+                    this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_GUARD)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_GUARD;
+                        BSSVideo.bProgressvideooffer = true;
+                        continue;
+                    }
+                    if (this.callId.endsWith(BSSVideo.HNS_POSTFIX_NEIGHBOR)) {
+                        this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NEIGHBOR;
+                        BSSVideo.bProgressvideooffer = false;
+                        continue;
+                    }
+                    this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                    BSSVideo.bProgressvideooffer = false;
+                    continue;
+                }
+                this.hnsOriginatorServiceType = BSSVideo.HNS_SERVICE_NONE;
+                this.hnsReceiverServiceType = BSSVideo.HNS_SERVICE_NONE;
+                BSSVideo.bProgressvideooffer = false;
+                continue;
+            }
+            if (token.startsWith("CSeq: ")) {
+                this.cseqH = token;
+                StringTokenizer fieldArray = new StringTokenizer(token, " ", true);
+                int tokenCount = 0;
+                while (fieldArray.hasMoreTokens()) {
+                    String fieldtoken = fieldArray.nextToken();
+                    if (fieldtoken.length() > 0 && fieldtoken.compareTo(" ") != 0) {
+                        tokenCount++;
+                        if (tokenCount == 2) {
+                            this.CSEQ_NUMBER = Integer.parseInt(fieldtoken);
+                            break;
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("Content-Type: ")) {
+                this.contenttypeH = token;
+                continue;
+            }
+            if (token.startsWith("c: ")) {
+                this.contenttypeH = token;
+                continue;
+            }
+            if (token.startsWith("Content-Length: ")) {
+                this.contentlengthH = token;
+                continue;
+            }
+            if (token.startsWith("l: ")) {
+                this.contentlengthH = token;
+                continue;
+            }
+            if (token.startsWith("User-Agent: ")) {
+                this.remoteuseragentH = token;
+                this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+                continue;
+            }
+            if (token.startsWith("P-Asserted-Identity: "))
+                this.passertedidentityH = token;
+        }
+        this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+        this.maxforwardH = "Max-Forwards: 70";
+        int audioport = SIPStack.getFreeAudioRtpPort();
+        if (audioport > 0)
+            constructSdp();
+        if (this.sdp != null && this.sdp.flag) {
+            this.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+            if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+            } else {
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+            }
+            this.sdp.setCodec(
+                    SIPStack.SIP_MEDIATYPE_AUDIO,
+                    RFC2833.payloadType,
+                    "telephone-event/8000");
+            this.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+        }
+        if (parseRemoteSdp(message))
+            if (this.remoteSdp != null &&
+                    this.remoteSdp.flag)
+                if (this.remoteSdp.audioM != null &&
+                        this.sdp != null && this.sdp.flag && this.sdp.audioM != null &&
+                        this.remoteSdp.audioM.flow != null &&
+                        this.remoteSdp.audioM.flow.length() > 0)
+                    if (this.remoteSdp.audioM.flow.compareTo("sendrecv") == 0) {
+                        this.sdp.audioM.setFlow("sendrecv");
+                    } else if (this.remoteSdp.audioM.flow.compareTo("sendonly") == 0) {
+                        this.sdp.audioM.setFlow("recvonly");
+                    } else if (this.remoteSdp.audioM.flow.compareTo("recvonly") == 0) {
+                        this.sdp.audioM.setFlow("sendonly");
+                    }
+        negotiateAudioCodec();
+        return true;
+    }
+
+    public boolean constructUPDATEHeaders(String message, String remoteIp, int remotePort) {
+        if (message == null || message.length() == 0)
+            return false;
+        resetUpdateheaders();
+        setUpdateheaders();
+        this.viaH = null;
+        this.viaArray = new StringBuffer();
+        this.routeH = null;
+        this.routeArray = new StringBuffer();
+        this.recordrouteH = null;
+        this.recordrouteArray = new StringBuffer();
+        this.message = message;
+        StringTokenizer tokenArray = new StringTokenizer(message, SIPStack.SIP_LINE_END, true);
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken().trim();
+            if (token.length() <= 0 ||
+                    token.compareTo("\r") == 0 ||
+                    token.compareTo("\n") == 0)
+                continue;
+            if (token.startsWith("From: ")) {
+                this.fromH = token;
+                int iS = this.fromH.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    int iE = this.fromH.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.fromH.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.fromH.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.fromTag = str.trim();
+                }
+                this.fromHeaderValue = token.substring(6);
+                System.out.println("FROM TAG:" + this.fromTag);
+                continue;
+            }
+            if (token.startsWith("f: ")) {
+                this.fromH = token;
+                int iS = this.fromH.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    int iE = this.fromH.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.fromH.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.fromH.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.fromTag = str.trim();
+                }
+                this.fromHeaderValue = token.substring(3);
+                System.out.println("FROM TAG:" + this.fromTag);
+                continue;
+            }
+            if (token.startsWith("To: ")) {
+                this.toH = token;
+                int iS = this.toH.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    int iE = this.toH.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.toH.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.toH.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.toTag = str.trim();
+                }
+                this.toHeaderValue = token.substring(4);
+                System.out.println("TO TAG:" + this.toTag);
+                continue;
+            }
+            if (token.startsWith("To: ")) {
+                this.toH = token;
+                int iS = this.toH.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    int iE = this.toH.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.toH.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.toH.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.toTag = str.trim();
+                }
+                this.toHeaderValue = token.substring(3);
+                System.out.println("TO TAG:" + this.toTag);
+                continue;
+            }
+            if (token.startsWith("Via: ")) {
+                if (this.viaH == null) {
+                    this.viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = "";
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            this.viaH = token.substring(0, index);
+                        } else {
+                            this.viaH = token;
+                        }
+                        index = this.viaH.indexOf(";rport=");
+                        if (index > 0)
+                            this.viaH = this.viaH.substring(0, index);
+                        this.viaH = String.valueOf(this.viaH) + ";received=" + remoteIp + ";rport=" + remotePort + ";branch=" + this.viaBranch;
+                    }
+                    this.viaArray.append(String.valueOf(this.viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("v: ")) {
+                if (this.viaH == null) {
+                    this.viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = branch;
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            this.viaH = token.substring(0, index);
+                        } else {
+                            this.viaH = token;
+                        }
+                        index = this.viaH.indexOf(";rport=");
+                        if (index > 0)
+                            this.viaH = this.viaH.substring(0, index);
+                        this.viaH = String.valueOf(this.viaH) + ";received=" + remoteIp + ";rport=" + remotePort + ";branch=" + this.viaBranch;
+                    }
+                    this.viaArray.append(String.valueOf(this.viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("Record-Route: ")) {
+                if (this.recordrouteH == null) {
+                    this.routeH = null;
+                    this.routeArray = new StringBuffer();
+                    this.recordrouteH = token;
+                    this.recordrouteArray.append(String.valueOf(this.recordrouteH) + SIPStack.SIP_LINE_END);
+                    this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                this.recordrouteArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("Contact: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("m: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("Call-ID: ")) {
+                this.callidH = token;
+                this.callId = token.substring(9).trim();
+                continue;
+            }
+            if (token.startsWith("i: ")) {
+                this.callidH = token;
+                this.callId = token.substring(3).trim();
+                continue;
+            }
+            if (token.startsWith("CSeq: ")) {
+                this.cseqH = token;
+                StringTokenizer fieldArray = new StringTokenizer(token, " ", true);
+                int tokenCount = 0;
+                while (fieldArray.hasMoreTokens()) {
+                    String fieldtoken = fieldArray.nextToken();
+                    if (fieldtoken.length() > 0 && fieldtoken.compareTo(" ") != 0) {
+                        tokenCount++;
+                        if (tokenCount == 2) {
+                            this.CSEQ_NUMBER = Integer.parseInt(fieldtoken);
+                            break;
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("Content-Type: ")) {
+                this.contenttypeH = token;
+                continue;
+            }
+            if (token.startsWith("c: ")) {
+                this.contenttypeH = token;
+                continue;
+            }
+            if (token.startsWith("Content-Length: ")) {
+                this.contentlengthH = token;
+                continue;
+            }
+            if (token.startsWith("l: ")) {
+                this.contentlengthH = token;
+                continue;
+            }
+            if (token.startsWith("User-Agent: ")) {
+                this.remoteuseragentH = token;
+                this.useragentH = "User-Agent: KwangHaeSoft SmartSip release 0100o";
+                continue;
+            }
+            if (token.startsWith("P-Asserted-Identity: "))
+                this.passertedidentityH = token;
+        }
+        this.allowH = "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO";
+        this.maxforwardH = "Max-Forwards: 70";
+        int audioport = this.updateHeaders.sdp.audioM.mediaPort;
+        if (audioport > 0)
+            constructSdp();
+        if (this.sdp != null && this.sdp.flag) {
+            this.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+            if (SIPStack.PRIMARY_CODEC_AUDIO == SIPStack.SIP_CODEC_G711U) {
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+            } else {
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711A,
+                        "PCMA/8000");
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        SIPStack.SIP_CODEC_G711U,
+                        "PCMU/8000");
+            }
+            this.sdp.setCodec(
+                    SIPStack.SIP_MEDIATYPE_AUDIO,
+                    RFC2833.payloadType,
+                    "telephone-event/8000");
+            this.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+        }
+        if (parseRemoteSdp(message))
+            if (this.remoteSdp != null &&
+                    this.remoteSdp.flag)
+                if (this.remoteSdp.audioM != null &&
+                        this.sdp != null && this.sdp.flag && this.sdp.audioM != null &&
+                        this.remoteSdp.audioM.flow != null &&
+                        this.remoteSdp.audioM.flow.length() > 0)
+                    if (this.remoteSdp.audioM.flow.compareTo("sendrecv") == 0) {
+                        this.sdp.audioM.setFlow("sendrecv");
+                    } else if (this.remoteSdp.audioM.flow.compareTo("sendonly") == 0) {
+                        this.sdp.audioM.setFlow("recvonly");
+                    } else if (this.remoteSdp.audioM.flow.compareTo("recvonly") == 0) {
+                        this.sdp.audioM.setFlow("sendonly");
+                    }
+        negotiateAudioCodec();
+        return true;
+    }
+
+    public void reverseRecordRoute(String message) {
+        if (message == null || message.length() == 0)
+            return;
+        this.recordrouteArray = null;
+        this.routeH = null;
+        StringTokenizer tokenArray = new StringTokenizer(message, SIPStack.SIP_LINE_END, true);
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken().trim();
+            if (token.length() <= 0 ||
+                    token.compareTo("\r") == 0 ||
+                    token.compareTo("\n") == 0)
+                continue;
+            if (token.startsWith("Record-Route: ")) {
+                this.routeH = token.substring(7).trim();
+                if (this.routeArray == null) {
+                    this.routeArray = new StringBuffer();
+                    this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                if (this.routeArray != null && this.routeArray.length() > 0) {
+                    this.routeArray.insert(0, String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                if (this.routeArray != null)
+                    this.routeArray.append(String.valueOf(token.substring(7)) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("Contact: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (token.startsWith("m: ")) {
+                this.contactH = token;
+                if (token.length() > 0) {
+                    int iS = 0;
+                    iS = token.indexOf("sip:");
+                    if (iS > 0) {
+                        String str = null;
+                        int iE = 0;
+                        iE = token.indexOf(">", iS);
+                        if (iE > 0) {
+                            str = token.substring(iS, iE);
+                        } else {
+                            str = token.substring(iS);
+                        }
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(";");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        iE = str.indexOf(" ");
+                        if (iE > 0)
+                            str = str.substring(0, iE);
+                        if (str.length() > 0)
+                            this.remoteContactUri = str;
+                        if (str.length() > 0) {
+                            iS = str.indexOf("@");
+                            if (iS > 0) {
+                                str = str.substring(iS + 1);
+                            } else {
+                                str = str.substring(4);
+                            }
+                            int iM = str.indexOf(":", iS);
+                            if (iM < 0) {
+                                this.remoteContactIp = str;
+                                this.remoteContactPort = 5060;
+                                continue;
+                            }
+                            this.remoteContactIp = str.substring(0, iM).trim();
+                            this.remoteContactPort = Integer.parseInt(str.substring(iM + 1).trim());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public String getViaArray(String message) {
+        if (message == null || message.length() == 0)
+            return null;
+        StringBuffer viaArray = new StringBuffer();
+        String viaH = null;
+        StringTokenizer tokenArray = new StringTokenizer(message, SIPStack.SIP_LINE_END, true);
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken().trim();
+            if (token.length() <= 0 ||
+                    token.compareTo("\r") == 0 ||
+                    token.compareTo("\n") == 0)
+                continue;
+            if (token.startsWith("Via: ")) {
+                if (viaH == null) {
+                    viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = "";
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            viaH = token.substring(0, index);
+                        } else {
+                            viaH = token;
+                        }
+                        index = viaH.indexOf(";rport=");
+                        if (index > 0)
+                            viaH = viaH.substring(0, index);
+                        viaH = String.valueOf(viaH) + ";received=" + this.remoteIp + ";rport=" + this.remotePort + ";branch=" + this.viaBranch;
+                    }
+                    viaArray.append(String.valueOf(viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+                continue;
+            }
+            if (token.startsWith("v: ")) {
+                if (viaH == null) {
+                    viaH = token;
+                    if (token.indexOf(";received=") < 0) {
+                        String branch = "";
+                        int index = token.indexOf(";branch=");
+                        if (index > 0)
+                            branch = token.substring(index + 8);
+                        if (branch != null && branch.length() > 0) {
+                            index = branch.indexOf(";");
+                            if (index > 0) {
+                                this.viaBranch = branch.substring(0, index);
+                            } else {
+                                this.viaBranch = branch;
+                            }
+                        } else {
+                            this.viaBranch = branch;
+                        }
+                        index = token.indexOf(";branch=");
+                        if (index > 0) {
+                            viaH = token.substring(0, index);
+                        } else {
+                            viaH = token;
+                        }
+                        index = viaH.indexOf(";rport=");
+                        if (index > 0)
+                            viaH = viaH.substring(0, index);
+                        viaH = String.valueOf(viaH) + ";received=" + this.remoteIp + ";rport=" + this.remotePort + ";branch=" + this.viaBranch;
+                    }
+                    viaArray.append(String.valueOf(viaH) + SIPStack.SIP_LINE_END);
+                    continue;
+                }
+                viaArray.append(String.valueOf(token) + SIPStack.SIP_LINE_END);
+            }
+        }
+        return viaArray.toString();
+    }
+
+    public boolean constructSdp() {
+        if (this.sdp != null && this.sdp.flag)
+            return false;
+        if (SIPStack.localSdpIp != null && SIPStack.localSdpIp.length() > 0 && SIPStack.usePrivateWiMax) {
+            this.sdp = new SIPSdp(this.dnis, this.localIp, SIPStack.localSdpIp);
+        } else {
+            this.sdp = new SIPSdp(this.dnis, this.localIp);
+        }
+        if (this.sdp != null && this.sdp.flag)
+            return true;
+        return false;
+    }
+
+    public boolean parseRemoteSdp(String message) {
+        if (message == null || message.length() == 0)
+            return false;
+        boolean bContinueParsing = true;
+        int iS = 0;
+        int iE = 0;
+        String header = null;
+        if (bContinueParsing) {
+            bContinueParsing = false;
+            iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Type: ");
+            if (iS > 0) {
+                iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                if (iS > 0 && iE > 0) {
+                    header = message.substring(iS + 2, iE);
+                    String headerValue = null;
+                    if (header != null && header.length() > 0)
+                        headerValue = header.substring(14);
+                    if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/sdp") == 0)
+                        bContinueParsing = true;
+                }
+            } else {
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "c: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(3);
+                        if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/sdp") == 0)
+                            bContinueParsing = true;
+                    }
+                }
+            }
+        }
+        iS = 0;
+        iE = 0;
+        header = null;
+        int contentLength = 0;
+        if (bContinueParsing) {
+            bContinueParsing = false;
+            iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Length: ");
+            if (iS > 0) {
+                iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                if (iS > 0 && iE > 0) {
+                    header = message.substring(iS + 2, iE);
+                    String headerValue = null;
+                    if (header != null && header.length() > 0)
+                        headerValue = header.substring(16);
+                    if (headerValue != null && headerValue.length() > 0) {
+                        contentLength = Integer.parseInt(headerValue);
+                        bContinueParsing = true;
+                    }
+                }
+            } else {
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "l: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(3);
+                        if (headerValue != null && headerValue.length() > 0) {
+                            contentLength = Integer.parseInt(headerValue);
+                            bContinueParsing = true;
+                        }
+                    }
+                }
+            }
+        }
+        iS = 0;
+        iE = 0;
+        header = null;
+        String body = null;
+        if (bContinueParsing) {
+            bContinueParsing = false;
+            iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_DOUBLEEND) + "v=0" + SIPStack.SIP_LINE_END);
+            if (iS > 0) {
+                body = message.substring(iS + 4);
+                if (body != null && body.length() >= contentLength)
+                    bContinueParsing = true;
+            }
+        }
+        if (bContinueParsing) {
+            this.remoteSdp = new SIPSdp(body);
+            if (this.remoteSdp != null && this.remoteSdp.flag)
+                return true;
+        }
+        return false;
+    }
+
+    public boolean parseDtmfSdp(String message, int dtmftype) {
+        if (message == null || message.length() == 0)
+            return false;
+        boolean bContinueParsing = true;
+        int iS = 0;
+        int iE = 0;
+        int dtmf = 0;
+        this.bDtmfdetected = false;
+        String header = null;
+        if (dtmftype == SIPStack.SIP_DTMFINFO_DTMFRELAY) {
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Type: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(14);
+                        if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/dtmf-relay") == 0)
+                            bContinueParsing = true;
+                    }
+                } else {
+                    iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "c: ");
+                    if (iS > 0) {
+                        iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                        if (iS > 0 && iE > 0) {
+                            header = message.substring(iS + 2, iE);
+                            String headerValue = null;
+                            if (header != null && header.length() > 0)
+                                headerValue = header.substring(3);
+                            if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/dtmf-relay") == 0)
+                                bContinueParsing = true;
+                        }
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            header = null;
+            int contentLength = 0;
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Length: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(16);
+                        if (headerValue != null && headerValue.length() > 0) {
+                            contentLength = Integer.parseInt(headerValue);
+                            bContinueParsing = true;
+                        }
+                    }
+                } else {
+                    iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "l: ");
+                    if (iS > 0) {
+                        iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                        if (iS > 0 && iE > 0) {
+                            header = message.substring(iS + 2, iE);
+                            String headerValue = null;
+                            if (header != null && header.length() > 0)
+                                headerValue = header.substring(3);
+                            if (headerValue != null && headerValue.length() > 0) {
+                                contentLength = Integer.parseInt(headerValue);
+                                bContinueParsing = true;
+                            }
+                        }
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            header = null;
+            String body = null;
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_DOUBLEEND) + "Signal=");
+                if (iS > 0) {
+                    body = message.substring(iS + 4);
+                    if (body != null && body.length() >= contentLength)
+                        bContinueParsing = true;
+                }
+            }
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                String sH = null;
+                iS = body.indexOf("Signal=");
+                if (iS >= 0)
+                    iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+                if (iS >= 0 && iE > iS) {
+                    sH = body.substring(iS + 7, iE).trim();
+                    dtmf = Integer.parseInt(sH);
+                    if (dtmf >= 0 && dtmf < 12) {
+                        bContinueParsing = true;
+                        this.detectedDtmf = dtmf;
+                        this.bDtmfdetected = true;
+                        this.dtmfDuration = 0;
+                    }
+                }
+                if (bContinueParsing) {
+                    iS = body.indexOf("Duration=");
+                    if (iS >= 0)
+                        iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+                    if (iS >= 0 && iE > iS) {
+                        sH = body.substring(iS + 9, iE).trim();
+                        this.dtmfDuration = Integer.parseInt(sH);
+                    }
+                }
+            }
+            return this.bDtmfdetected;
+        }
+        if (dtmftype == SIPStack.SIP_DTMFINFO_DTMF) {
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Type: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(14);
+                        if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/dtmf") == 0)
+                            bContinueParsing = true;
+                    }
+                } else {
+                    iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "c: ");
+                    if (iS > 0) {
+                        iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                        if (iS > 0 && iE > 0) {
+                            header = message.substring(iS + 2, iE);
+                            String headerValue = null;
+                            if (header != null && header.length() > 0)
+                                headerValue = header.substring(3);
+                            if (headerValue != null && headerValue.length() > 0 && headerValue.toLowerCase().compareTo("application/dtmf") == 0)
+                                bContinueParsing = true;
+                        }
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            header = null;
+            int contentLength = 0;
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "Content-Length: ");
+                if (iS > 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                    if (iS > 0 && iE > 0) {
+                        header = message.substring(iS + 2, iE);
+                        String headerValue = null;
+                        if (header != null && header.length() > 0)
+                            headerValue = header.substring(16);
+                        if (headerValue != null && headerValue.length() > 0) {
+                            contentLength = Integer.parseInt(headerValue);
+                            bContinueParsing = true;
+                        }
+                    }
+                } else {
+                    iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "l: ");
+                    if (iS > 0) {
+                        iE = message.indexOf(SIPStack.SIP_LINE_END, iS + 2);
+                        if (iS > 0 && iE > 0) {
+                            header = message.substring(iS + 2, iE);
+                            String headerValue = null;
+                            if (header != null && header.length() > 0)
+                                headerValue = header.substring(3);
+                            if (headerValue != null && headerValue.length() > 0) {
+                                contentLength = Integer.parseInt(headerValue);
+                                bContinueParsing = true;
+                            }
+                        }
+                    }
+                }
+            }
+            iS = 0;
+            iE = 0;
+            header = null;
+            String body = null;
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                iS = message.indexOf(SIPStack.SIP_LINE_DOUBLEEND);
+                if (iS > 0) {
+                    body = message.substring(iS + 4);
+                    if (body != null && body.length() >= contentLength)
+                        bContinueParsing = true;
+                }
+            }
+            if (bContinueParsing) {
+                bContinueParsing = false;
+                String sH = null;
+                iS = 0;
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+                if (iE > iS) {
+                    sH = body.substring(iS, iE).trim();
+                    dtmf = Integer.parseInt(sH);
+                    if (dtmf >= 0 && dtmf < 12) {
+                        bContinueParsing = true;
+                        this.detectedDtmf = dtmf;
+                        this.bDtmfdetected = true;
+                        this.dtmfDuration = 0;
+                    }
+                }
+            }
+            return this.bDtmfdetected;
+        }
+        return false;
+    }
+
+    public boolean negotiateAudioCodec() {
+        if (this.sdp != null && this.sdp.flag && this.sdp.audioM != null && this.sdp.audioM.flag &&
+                this.remoteSdp != null && this.remoteSdp.flag && this.remoteSdp.audioM != null &&
+                this.remoteSdp.audioM.flag)
+            if (this.callDirection == SIPStack.SIP_CALLDIRECTION_OUT) {
+                int finalCodec = this.remoteSdp.audioM.negotiateAudioCodec(this.sdp.audioM.codecS.toString());
+                if (finalCodec >= 0) {
+                    this.sdp.audioM.setCommonCodec(finalCodec);
+                    return true;
+                }
+            } else if (this.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+                int finalCodec = this.sdp.audioM.negotiateAudioCodec(this.remoteSdp.audioM.codecS.toString());
+                if (finalCodec >= 0) {
+                    this.remoteSdp.audioM.setCommonCodec(finalCodec);
+                    return true;
+                }
+            }
+        return false;
+    }
+
+    public boolean negotiateVideoCodec() {
+        return true;
+    }
+
+    public void exceptionTI() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("IDLE CALL EXCEPTION occurred.");
+        resetCall();
+    }
+
+    public void exceptionT0() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("INVITING CALL EXCEPTION occurred.");
+        resetCall();
+    }
+
+    public void exceptionT1() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("PROCEEDING CALL EXCEPTION occurred.");
+    }
+
+    public void exceptionT2() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("PROGRESSING CALL EXCEPTION occurred.");
+    }
+
+    public void exceptionT3() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("ACCEPTED CALL EXCEPTION occurred.");
+    }
+
+    public void exceptionT4() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("CONNECTED CALL EXCEPTION occurred.");
+    }
+
+    public void exceptionT5() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("DISCONNECTING CALL EXCEPTION occurred.");
+        resetCall();
+    }
+
+    public void exceptionT6() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("TERMINATING CALL EXCEPTION occurred.");
+        resetCall();
+    }
+
+    public void exceptionT7() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("OFFERRED CALL EXCEPTION occurred.");
+    }
+
+    public void exceptionT8() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("CANCELLING CALL EXCEPTION occurred.");
+        resetCall();
+    }
+
+    public void setUpdateheaders() {
+        if (this.updateHeaders == null)
+            return;
+        this.updateHeaders.commandLine = this.commandLine;
+        this.updateHeaders.viaH = this.viaH;
+        this.updateHeaders.viaArray = this.viaArray;
+        this.updateHeaders.routeH = this.routeH;
+        this.updateHeaders.routeArray = this.routeArray;
+        this.updateHeaders.recordrouteH = this.recordrouteH;
+        this.updateHeaders.recordrouteArray = this.recordrouteArray;
+        this.updateHeaders.maxforwardH = this.maxforwardH;
+        this.updateHeaders.contactH = this.contactH;
+        this.updateHeaders.toH = this.toH;
+        this.updateHeaders.fromH = this.fromH;
+        this.updateHeaders.callidH = this.callidH;
+        this.updateHeaders.cseqH = this.cseqH;
+        this.updateHeaders.expiresH = this.expiresH;
+        this.updateHeaders.allowH = this.allowH;
+        this.updateHeaders.useragentH = this.useragentH;
+        this.updateHeaders.remoteuseragentH = this.remoteuseragentH;
+        this.updateHeaders.contentlengthH = this.contentlengthH;
+        this.updateHeaders.contenttypeH = this.contenttypeH;
+        this.updateHeaders.authorizationINVITEH = this.authorizationINVITEH;
+        this.updateHeaders.authorizationCANCELH = this.authorizationCANCELH;
+        this.updateHeaders.authorizationBYEH = this.authorizationBYEH;
+        this.updateHeaders.authorizationACKH = this.authorizationACKH;
+        this.updateHeaders.passertedidentityH = this.passertedidentityH;
+        this.updateHeaders.serverIp = this.serverIp;
+        this.updateHeaders.serverPort = this.serverPort;
+        this.updateHeaders.serverDomain = this.serverDomain;
+        this.updateHeaders.remoteIp = this.remoteIp;
+        this.updateHeaders.remotePort = this.remotePort;
+        this.updateHeaders.remoteContactIp = this.remoteContactIp;
+        this.updateHeaders.remoteContactPort = this.remoteContactPort;
+        this.updateHeaders.remoteContactUri = this.remoteContactUri;
+        this.updateHeaders.localIp = this.localIp;
+        this.updateHeaders.localPort = this.localPort;
+        this.updateHeaders.id = this.id;
+        this.updateHeaders.cid = this.cid;
+        this.updateHeaders.authid = this.authid;
+        this.updateHeaders.authpassword = this.authpassword;
+        this.updateHeaders.fromTag = this.fromTag;
+        this.updateHeaders.toTag = this.toTag;
+        this.updateHeaders.fromHeaderValue = this.fromHeaderValue;
+        this.updateHeaders.toHeaderValue = this.toHeaderValue;
+        this.updateHeaders.callId = this.callId;
+        this.updateHeaders.dnis = this.dnis;
+        this.updateHeaders.CSEQ_NUMBER = this.CSEQ_NUMBER;
+        this.updateHeaders.INVITE_CSEQ = this.INVITE_CSEQ;
+        this.updateHeaders.CANCEL_CSEQ = this.CANCEL_CSEQ;
+        this.updateHeaders.ACK_CSEQ = this.ACK_CSEQ;
+        this.updateHeaders.BYE_CSEQ = this.BYE_CSEQ;
+        this.updateHeaders.callDirection = this.callDirection;
+        this.updateHeaders.viaBranch = this.viaBranch;
+        this.updateHeaders.callState = this.callState;
+        this.updateHeaders.callMode = this.callMode;
+        this.updateHeaders.callTime_TI = this.callTime_TI;
+        this.updateHeaders.callTime_T0 = this.callTime_T0;
+        this.updateHeaders.callTime_T00 = this.callTime_T00;
+        this.updateHeaders.invitingTimes = this.invitingTimes;
+        this.updateHeaders.callTime_T1 = this.callTime_T1;
+        this.updateHeaders.callTime_T2 = this.callTime_T2;
+        this.updateHeaders.callTime_T3 = this.callTime_T3;
+        this.updateHeaders.callTime_T4 = this.callTime_T4;
+        this.updateHeaders.callTime_T40 = this.callTime_T40;
+        this.updateHeaders.callTime_T5 = this.callTime_T5;
+        this.updateHeaders.callTime_T6 = this.callTime_T6;
+        this.updateHeaders.callTime_T7 = this.callTime_T7;
+        this.updateHeaders.callTime_T8 = this.callTime_T8;
+        this.updateHeaders.callTime_T9 = this.callTime_T9;
+        this.updateHeaders.expiresTI = this.expiresTI;
+        this.updateHeaders.expiresT0 = this.expiresT0;
+        this.updateHeaders.expiresT1 = this.expiresT1;
+        this.updateHeaders.expiresT2 = this.expiresT2;
+        this.updateHeaders.expiresT3 = this.expiresT3;
+        this.updateHeaders.expiresT4 = this.expiresT4;
+        this.updateHeaders.expiresT5 = this.expiresT5;
+        this.updateHeaders.expiresT6 = this.expiresT6;
+        this.updateHeaders.expiresT7 = this.expiresT7;
+        this.updateHeaders.expiresT8 = this.expiresT8;
+        this.updateHeaders.expiresT9 = this.expiresT9;
+        this.updateHeaders.sdp = this.sdp;
+        this.updateHeaders.remoteSdp = this.remoteSdp;
+        this.updateHeaders.message = this.message;
+        this.commandLine = null;
+        this.viaH = null;
+        this.viaArray = null;
+        this.routeH = null;
+        this.routeArray = null;
+        this.recordrouteH = null;
+        this.recordrouteArray = null;
+        this.maxforwardH = null;
+        this.contactH = null;
+        this.toH = null;
+        this.fromH = null;
+        this.callidH = null;
+        this.cseqH = null;
+        this.expiresH = null;
+        this.allowH = null;
+        this.useragentH = null;
+        this.remoteuseragentH = null;
+        this.contentlengthH = null;
+        this.contenttypeH = null;
+        this.authorizationINVITEH = null;
+        this.authorizationCANCELH = null;
+        this.authorizationBYEH = null;
+        this.authorizationACKH = null;
+        this.passertedidentityH = null;
+        this.fromTag = null;
+        this.toTag = null;
+        this.callId = null;
+        this.viaBranch = null;
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.message = null;
+        this.updateHeaders.flag = true;
+    }
+
+    public void setUpdateheaders(String flow) {
+        if (this.updateHeaders == null)
+            return;
+        this.updateHeaders.commandLine = this.commandLine;
+        this.updateHeaders.viaH = this.viaH;
+        this.updateHeaders.viaArray = this.viaArray;
+        this.updateHeaders.routeH = this.routeH;
+        this.updateHeaders.routeArray = this.routeArray;
+        this.updateHeaders.recordrouteH = this.recordrouteH;
+        this.updateHeaders.recordrouteArray = this.recordrouteArray;
+        this.updateHeaders.maxforwardH = this.maxforwardH;
+        this.updateHeaders.contactH = this.contactH;
+        this.updateHeaders.toH = this.toH;
+        this.updateHeaders.fromH = this.fromH;
+        this.updateHeaders.callidH = this.callidH;
+        this.updateHeaders.cseqH = this.cseqH;
+        this.updateHeaders.expiresH = this.expiresH;
+        this.updateHeaders.allowH = this.allowH;
+        this.updateHeaders.useragentH = this.useragentH;
+        this.updateHeaders.remoteuseragentH = this.remoteuseragentH;
+        this.updateHeaders.contentlengthH = this.contentlengthH;
+        this.updateHeaders.contenttypeH = this.contenttypeH;
+        this.updateHeaders.authorizationINVITEH = this.authorizationINVITEH;
+        this.updateHeaders.authorizationCANCELH = this.authorizationCANCELH;
+        this.updateHeaders.authorizationBYEH = this.authorizationBYEH;
+        this.updateHeaders.authorizationACKH = this.authorizationACKH;
+        this.updateHeaders.passertedidentityH = this.passertedidentityH;
+        this.updateHeaders.serverIp = this.serverIp;
+        this.updateHeaders.serverPort = this.serverPort;
+        this.updateHeaders.serverDomain = this.serverDomain;
+        this.updateHeaders.remoteIp = this.remoteIp;
+        this.updateHeaders.remotePort = this.remotePort;
+        this.updateHeaders.remoteContactIp = this.remoteContactIp;
+        this.updateHeaders.remoteContactPort = this.remoteContactPort;
+        this.updateHeaders.remoteContactUri = this.remoteContactUri;
+        this.updateHeaders.localIp = this.localIp;
+        this.updateHeaders.localPort = this.localPort;
+        this.updateHeaders.id = this.id;
+        this.updateHeaders.cid = this.cid;
+        this.updateHeaders.authid = this.authid;
+        this.updateHeaders.authpassword = this.authpassword;
+        this.updateHeaders.fromTag = this.fromTag;
+        this.updateHeaders.toTag = this.toTag;
+        this.updateHeaders.fromHeaderValue = this.fromHeaderValue;
+        this.updateHeaders.toHeaderValue = this.toHeaderValue;
+        this.updateHeaders.callId = this.callId;
+        this.updateHeaders.dnis = this.dnis;
+        this.updateHeaders.CSEQ_NUMBER = this.CSEQ_NUMBER;
+        this.updateHeaders.INVITE_CSEQ = this.INVITE_CSEQ;
+        this.updateHeaders.CANCEL_CSEQ = this.CANCEL_CSEQ;
+        this.updateHeaders.ACK_CSEQ = this.ACK_CSEQ;
+        this.updateHeaders.BYE_CSEQ = this.BYE_CSEQ;
+        this.updateHeaders.callDirection = this.callDirection;
+        this.updateHeaders.viaBranch = this.viaBranch;
+        this.updateHeaders.callState = this.callState;
+        this.updateHeaders.callMode = this.callMode;
+        this.updateHeaders.callTime_TI = this.callTime_TI;
+        this.updateHeaders.callTime_T0 = this.callTime_T0;
+        this.updateHeaders.callTime_T00 = this.callTime_T00;
+        this.updateHeaders.invitingTimes = this.invitingTimes;
+        this.updateHeaders.callTime_T1 = this.callTime_T1;
+        this.updateHeaders.callTime_T2 = this.callTime_T2;
+        this.updateHeaders.callTime_T3 = this.callTime_T3;
+        this.updateHeaders.callTime_T4 = this.callTime_T4;
+        this.updateHeaders.callTime_T40 = this.callTime_T40;
+        this.updateHeaders.callTime_T5 = this.callTime_T5;
+        this.updateHeaders.callTime_T6 = this.callTime_T6;
+        this.updateHeaders.callTime_T7 = this.callTime_T7;
+        this.updateHeaders.callTime_T8 = this.callTime_T8;
+        this.updateHeaders.callTime_T9 = this.callTime_T9;
+        this.updateHeaders.expiresTI = this.expiresTI;
+        this.updateHeaders.expiresT0 = this.expiresT0;
+        this.updateHeaders.expiresT1 = this.expiresT1;
+        this.updateHeaders.expiresT2 = this.expiresT2;
+        this.updateHeaders.expiresT3 = this.expiresT3;
+        this.updateHeaders.expiresT4 = this.expiresT4;
+        this.updateHeaders.expiresT5 = this.expiresT5;
+        this.updateHeaders.expiresT6 = this.expiresT6;
+        this.updateHeaders.expiresT7 = this.expiresT7;
+        this.updateHeaders.expiresT8 = this.expiresT8;
+        this.updateHeaders.expiresT9 = this.expiresT9;
+        this.updateHeaders.sdp = this.sdp;
+        this.updateHeaders.remoteSdp = this.remoteSdp;
+        this.updateHeaders.message = this.message;
+        this.commandLine = null;
+        this.viaH = null;
+        this.viaArray = null;
+        this.recordrouteH = null;
+        this.recordrouteArray = null;
+        this.maxforwardH = null;
+        this.contactH = null;
+        if (this.updateHeaders.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            if (this.updateHeaders.fromH != null && this.updateHeaders.fromH.length() > 5)
+                if (this.updateHeaders.fromH.startsWith("f: ")) {
+                    this.toH = "t:" + this.updateHeaders.fromH.substring(2);
+                } else {
+                    this.toH = "To:" + this.updateHeaders.fromH.substring(5);
+                }
+            if (this.updateHeaders.toH != null && this.updateHeaders.toH.length() > 3)
+                if (this.updateHeaders.toH.startsWith("t: ")) {
+                    this.fromH = "From:" + this.updateHeaders.toH.substring(2);
+                } else {
+                    this.fromH = "From:" + this.updateHeaders.toH.substring(3);
+                }
+            this.fromTag = this.updateHeaders.toTag;
+            this.toTag = this.updateHeaders.fromTag;
+        }
+        this.cseqH = null;
+        this.expiresH = null;
+        this.allowH = null;
+        this.useragentH = null;
+        this.remoteuseragentH = null;
+        this.contentlengthH = null;
+        this.contenttypeH = null;
+        this.viaBranch = null;
+        if (this.updateHeaders.callDirection == SIPStack.SIP_CALLDIRECTION_IN) {
+            this.authorizationINVITEH = null;
+            this.authorizationCANCELH = null;
+            this.authorizationBYEH = null;
+            this.authorizationACKH = null;
+        }
+        this.passertedidentityH = null;
+        this.callState = 20;
+        this.callMode = SIPStack.SIP_CALLMODE_HOLD;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.sdp = null;
+        this.remoteSdp = null;
+        int audioport = this.updateHeaders.sdp.audioM.mediaPort;
+        if (audioport > 0)
+            constructSdp();
+        if (this.sdp != null && this.sdp.flag) {
+            this.sdp.setMediaPort(SIPStack.SIP_MEDIATYPE_AUDIO, audioport);
+            if (this.sdp.audioM != null) {
+                if (this.updateHeaders.sdp.audioM.commonCodec == SIPStack.SIP_CODEC_G711U) {
+                    this.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711U,
+                            "PCMU/8000");
+                } else if (this.updateHeaders.sdp.audioM.commonCodec == SIPStack.SIP_CODEC_G711A) {
+                    this.sdp.setCodec(
+                            SIPStack.SIP_MEDIATYPE_AUDIO,
+                            SIPStack.SIP_CODEC_G711A,
+                            "PCMA/8000");
+                }
+                this.sdp.setCodec(
+                        SIPStack.SIP_MEDIATYPE_AUDIO,
+                        RFC2833.payloadType,
+                        "telephone-event/8000");
+                this.sdp.setFmtpDescribe(SIPStack.SIP_MEDIATYPE_AUDIO, RFC2833.payloadType, "0-15");
+                this.sdp.audioM.setFlow(flow);
+            }
+        }
+        this.message = null;
+        this.updateHeaders.flag = true;
+    }
+
+    public void restoreUpdateheaders() {
+        if (this.updateHeaders == null || !this.updateHeaders.flag)
+            return;
+        this.commandLine = this.updateHeaders.commandLine;
+        this.viaH = this.updateHeaders.viaH;
+        this.viaArray = this.updateHeaders.viaArray;
+        this.routeH = this.updateHeaders.routeH;
+        this.routeArray = this.updateHeaders.routeArray;
+        this.recordrouteH = this.updateHeaders.recordrouteH;
+        this.recordrouteArray = this.updateHeaders.recordrouteArray;
+        this.maxforwardH = this.updateHeaders.maxforwardH;
+        this.contactH = this.updateHeaders.contactH;
+        this.toH = this.updateHeaders.toH;
+        this.fromH = this.updateHeaders.fromH;
+        this.callidH = this.updateHeaders.callidH;
+        this.cseqH = this.updateHeaders.cseqH;
+        this.expiresH = this.updateHeaders.expiresH;
+        this.allowH = this.updateHeaders.allowH;
+        this.useragentH = this.updateHeaders.useragentH;
+        this.remoteuseragentH = this.updateHeaders.remoteuseragentH;
+        this.contentlengthH = this.updateHeaders.contentlengthH;
+        this.contenttypeH = this.updateHeaders.contenttypeH;
+        this.authorizationINVITEH = this.updateHeaders.authorizationINVITEH;
+        this.authorizationCANCELH = this.updateHeaders.authorizationCANCELH;
+        this.authorizationBYEH = this.updateHeaders.authorizationBYEH;
+        this.authorizationACKH = this.updateHeaders.authorizationACKH;
+        this.passertedidentityH = this.updateHeaders.passertedidentityH;
+        this.serverIp = this.updateHeaders.serverIp;
+        this.serverPort = this.updateHeaders.serverPort;
+        this.serverDomain = this.updateHeaders.serverDomain;
+        this.remoteIp = this.updateHeaders.remoteIp;
+        this.remotePort = this.updateHeaders.remotePort;
+        this.remoteContactIp = this.updateHeaders.remoteContactIp;
+        this.remoteContactPort = this.updateHeaders.remoteContactPort;
+        this.remoteContactUri = this.updateHeaders.remoteContactUri;
+        this.localIp = this.updateHeaders.localIp;
+        this.localPort = this.updateHeaders.localPort;
+        this.id = this.updateHeaders.id;
+        this.cid = this.updateHeaders.cid;
+        this.authid = this.updateHeaders.authid;
+        this.authpassword = this.updateHeaders.authpassword;
+        this.fromTag = this.updateHeaders.fromTag;
+        this.toTag = this.updateHeaders.toTag;
+        this.fromHeaderValue = this.updateHeaders.fromHeaderValue;
+        this.toHeaderValue = this.updateHeaders.toHeaderValue;
+        this.callId = this.updateHeaders.callId;
+        this.dnis = this.updateHeaders.dnis;
+        this.CSEQ_NUMBER = this.updateHeaders.CSEQ_NUMBER;
+        this.INVITE_CSEQ = this.updateHeaders.INVITE_CSEQ;
+        this.CANCEL_CSEQ = this.updateHeaders.CANCEL_CSEQ;
+        this.ACK_CSEQ = this.updateHeaders.ACK_CSEQ;
+        this.BYE_CSEQ = this.updateHeaders.BYE_CSEQ;
+        this.callDirection = this.updateHeaders.callDirection;
+        this.viaBranch = this.updateHeaders.viaBranch;
+        this.callState = this.updateHeaders.callState;
+        this.callMode = this.updateHeaders.callMode;
+        this.callTime_TI = this.updateHeaders.callTime_TI;
+        this.callTime_T0 = this.updateHeaders.callTime_T0;
+        this.callTime_T00 = this.updateHeaders.callTime_T00;
+        this.invitingTimes = this.updateHeaders.invitingTimes;
+        this.callTime_T1 = this.updateHeaders.callTime_T1;
+        this.callTime_T2 = this.updateHeaders.callTime_T2;
+        this.callTime_T3 = this.updateHeaders.callTime_T3;
+        this.callTime_T4 = this.updateHeaders.callTime_T4;
+        this.callTime_T40 = this.updateHeaders.callTime_T40;
+        this.callTime_T5 = this.updateHeaders.callTime_T5;
+        this.callTime_T6 = this.updateHeaders.callTime_T6;
+        this.callTime_T7 = this.updateHeaders.callTime_T7;
+        this.callTime_T8 = this.updateHeaders.callTime_T8;
+        this.callTime_T9 = this.updateHeaders.callTime_T9;
+        this.expiresTI = this.updateHeaders.expiresTI;
+        this.expiresT0 = this.updateHeaders.expiresT0;
+        this.expiresT1 = this.updateHeaders.expiresT1;
+        this.expiresT2 = this.updateHeaders.expiresT2;
+        this.expiresT3 = this.updateHeaders.expiresT3;
+        this.expiresT4 = this.updateHeaders.expiresT4;
+        this.expiresT5 = this.updateHeaders.expiresT5;
+        this.expiresT6 = this.updateHeaders.expiresT6;
+        this.expiresT7 = this.updateHeaders.expiresT7;
+        this.expiresT8 = this.updateHeaders.expiresT8;
+        this.expiresT9 = this.updateHeaders.expiresT9;
+        this.sdp = this.updateHeaders.sdp;
+        this.remoteSdp = this.updateHeaders.remoteSdp;
+        this.message = this.updateHeaders.message;
+        this.updateHeaders.flag = false;
+    }
+
+    public void resetUpdateheaders() {
+        if (this.updateHeaders == null || !this.updateHeaders.flag)
+            return;
+        this.updateHeaders.reset();
+    }
+
+    public boolean isCurrentCall(String message) {
+        try {
+            SIPHeader sipHeader = new SIPHeader(message, SIPStack.SIP_HEADERTYPE_CALLID);
+            if (sipHeader != null && sipHeader.flag)
+                if (sipHeader.headerValue != null &&
+                        sipHeader.headerValue.length() > 0 &&
+                        this.callId != null &&
+                        sipHeader.headerValue.compareTo(this.callId) == 0)
+                    return true;
+        } catch (Exception exception) {}
+        return false;
+    }
+
+    public String getCallState() {
+        switch (this.callState) {
+            case 0:
+                return "Idle";
+            case 1:
+                return "Inviting";
+            case 2:
+                return "Offerred";
+            case 3:
+                return "Proceeding";
+            case 4:
+                return "Progressing";
+            case 5:
+                return "Accepted";
+            case 6:
+                return "Remoteaccepted";
+            case 7:
+                return "Connected";
+            case 8:
+                return "Disconnecting";
+            case 9:
+                return "Terminating";
+            case 10:
+                return "Unauthorized";
+            case 11:
+                return "Cancelling";
+            case 13:
+                return "Recancelling";
+            case 14:
+                return "Cancelremoteaccepted";
+            case 12:
+                return "Cancelled";
+            case 15:
+                return "Rejected";
+            case 16:
+                return "Redirected";
+            case 20:
+                return "Updating";
+            case 21:
+                return "Updateproceeding";
+            case 22:
+                return "Updateprogressing";
+            case 23:
+                return "Updateofferred";
+            case 24:
+                return "Updateaccepted";
+            case 25:
+                return "Updaterejected";
+            case 26:
+                return "Updateremoteaccepted";
+            case 27:
+                return "Updateremoterejected";
+            case 28:
+                return "Updateunauthorized";
+            case 29:
+                return "Updateredirected";
+        }
+        return "Undefined";
+    }
+}

+ 362 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPG711.java

@@ -0,0 +1,362 @@
+package bssoft.stack.sip;
+
+public class SIPG711 {
+    static final int SIGN_BIT = 128;
+
+    static final int QUANT_MASK = 15;
+
+    static final int NSEGS = 8;
+
+    static final int SEG_SHIFT = 4;
+
+    static final int SEG_MASK = 112;
+
+    static final int[] seg_end = new int[] { 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 };
+
+    static final int[] _u2a = new int[] {
+            1, 1, 2, 2, 3, 3, 4, 4,
+
+            5, 5,
+            6, 6, 7, 7, 8, 8,
+
+            9, 10, 11, 12,
+            13, 14, 15, 16,
+
+            17, 18, 19, 20, 21, 22,
+            23, 24,
+
+            25, 27, 29, 31, 33, 34, 35, 36,
+            37, 38, 39, 40, 41, 42, 43, 44,
+
+            46, 48,
+            49, 50, 51, 52, 53, 54,
+
+            55, 56, 57, 58,
+            59, 60, 61, 62,
+
+            64, 65, 66, 67, 68, 69,
+            70, 71,
+
+            72, 73, 74, 75, 76, 77, 78, 79,
+            81, 82, 83, 84, 85, 86, 87, 88,
+
+            89, 90,
+            91, 92, 93, 94, 95, 96,
+
+            97, 98, 99, 100,
+            101, 102, 103, 104,
+
+            105, 106, 107, 108, 109, 110,
+            111, 112,
+
+            113, 114, 115, 116, 117, 118, 119, 120,
+            121, 122, 123, 124, 125, 126, 127, 128 };
+
+    static final int[] _a2u = new int[] {
+            1, 3, 5, 7, 9, 11, 13, 15,
+
+            16, 17,
+            18, 19, 20, 21, 22, 23,
+
+            24, 25, 26, 27,
+            28, 29, 30, 31,
+
+            32, 32, 33, 33, 34, 34,
+            35, 35,
+
+            36, 37, 38, 39, 40, 41, 42, 43,
+            44, 45, 46, 47, 48, 48, 49, 49,
+
+            50, 51,
+            52, 53, 54, 55, 56, 57,
+
+            58, 59, 60, 61,
+            62, 63, 64, 64,
+
+            65, 66, 67, 68, 69, 70,
+            71, 72,
+
+            73, 74, 75, 76, 77, 78, 79, 79,
+            80, 81, 82, 83, 84, 85, 86, 87,
+
+            88, 89,
+            90, 91, 92, 93, 94, 95,
+
+            96, 97, 98, 99,
+            100, 101, 102, 103,
+
+            104, 105, 106, 107, 108, 109,
+            110, 111,
+
+            112, 113, 114, 115, 116, 117, 118, 119,
+            120, 121, 122, 123, 124, 125, 126, 127 };
+
+    public static final int BIAS = 132;
+
+    static int search(int val, int[] table) {
+        for (int i = 0; i < table.length; ) {
+            if (val <= table[i])
+                return i;
+            i++;
+        }
+        return table.length;
+    }
+
+    public static int linear2alaw(int pcm_val) {
+        int mask;
+        if (pcm_val >= 0) {
+            mask = 213;
+        } else {
+            mask = 85;
+            pcm_val = -pcm_val - 8;
+        }
+        int seg = search(pcm_val, seg_end);
+        if (seg >= 8)
+            return 0x7F ^ mask;
+        int aval = seg << 4;
+        if (seg < 2) {
+            aval |= pcm_val >> 4 & 0xF;
+        } else {
+            aval |= pcm_val >> seg + 3 & 0xF;
+        }
+        return aval ^ mask;
+    }
+
+    public static int alaw2linear(int a_val) {
+        a_val ^= 0x55;
+        int t = (a_val & 0xF) << 4;
+        int seg = (a_val & 0x70) >> 4;
+        switch (seg) {
+            case 0:
+                t += 8;
+                break;
+            case 1:
+                t += 264;
+                break;
+            default:
+                t += 264;
+                t <<= seg - 1;
+                break;
+        }
+        return ((a_val & 0x80) != 0) ? t : -t;
+    }
+
+    public static int linear2ulaw(int pcm_val) {
+        int mask;
+        if (pcm_val < 0) {
+            pcm_val = 132 - pcm_val;
+            mask = 127;
+        } else {
+            pcm_val += 132;
+            mask = 255;
+        }
+        int seg = search(pcm_val, seg_end);
+        if (seg >= 8)
+            return 0x7F ^ mask;
+        int uval = seg << 4 | pcm_val >> seg + 3 & 0xF;
+        return uval ^ mask;
+    }
+
+    public static int ulaw2linear(int u_val) {
+        u_val ^= 0xFFFFFFFF;
+        int t = ((u_val & 0xF) << 3) + 132;
+        t <<= (u_val & 0x70) >> 4;
+        return ((u_val & 0x80) != 0) ? (132 - t) : (t - 132);
+    }
+
+    public static int alaw2ulaw(int aval) {
+        aval &= 0xFF;
+        return ((aval & 0x80) != 0) ? (0xFF ^ _a2u[aval ^ 0xD5]) : (0x7F ^ _a2u[aval ^ 0x55]);
+    }
+
+    public static int ulaw2alaw(int uval) {
+        uval &= 0xFF;
+        return ((uval & 0x80) != 0) ? (0xD5 ^ _u2a[0xFF ^ uval] - 1) : (0x55 ^ _u2a[0x7F ^ uval] - 1);
+    }
+
+    public static int encode2ULaw(short[] src, int srcsize, byte[] dest, int start) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return 0;
+        int encsize = srcsize;
+        for (int i = 0; i < encsize; i++)
+            dest[start + i] = (byte)linear2ulaw(src[i]);
+        return encsize + start;
+    }
+
+    public static int encode2ULawExt(byte[] src, int srcsize, byte[] dest, int start) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return 0;
+        int encsize = srcsize / 2;
+        int val = 0;
+        int val_ = 0;
+        for (int i = 0; i < encsize; i++) {
+            val = src[2 * i + 1];
+            val_ = src[2 * i];
+            val = val << 8 & 0xFFFFFF00;
+            val_ &= 0xFF;
+            val |= val_;
+            dest[start + i] = (byte)linear2ulaw(val);
+        }
+        return encsize + start;
+    }
+
+    public static int encode2ALaw(short[] src, int srcsize, byte[] dest, int start) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return 0;
+        int encsize = srcsize;
+        for (int i = 0; i < encsize; i++)
+            dest[start + i] = (byte)linear2alaw(src[i]);
+        return encsize + start;
+    }
+
+    public static int encode2ALawExt(byte[] src, int srcsize, byte[] dest, int start) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return 0;
+        int encsize = srcsize / 2;
+        int val = 0;
+        int val_ = 0;
+        for (int i = 0; i < encsize; i++) {
+            val = src[2 * i + 1];
+            val_ = src[2 * i];
+            val = val << 8 & 0xFFFFFF00;
+            val_ &= 0xFF;
+            val |= val_;
+            dest[start + i] = (byte)linear2alaw(val);
+        }
+        return encsize + start;
+    }
+
+    public static short[] decodeULaw(byte[] src, int start, int srcsize) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return null;
+        short[] decbuffer = new short[srcsize];
+        for (int i = 0; i < srcsize; i++)
+            decbuffer[i] = (short)ulaw2linear(src[i + start] & 0xFF);
+        return decbuffer;
+    }
+
+    public static byte[] decodeULawExt(byte[] src, int start, int srcsize) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return null;
+        byte[] decbuffer = new byte[srcsize * 2];
+        int val = 0;
+        for (int i = 0; i < srcsize; i++) {
+            val = ulaw2linear(src[i + start] & 0xFF);
+            decbuffer[2 * i + 1] = (byte)(val >> 8);
+            decbuffer[2 * i] = (byte)(val << 24 >> 24);
+        }
+        return decbuffer;
+    }
+
+    public static boolean decodeULawExt(byte[] src, int start, int srcsize, byte[] decbuffer) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return false;
+        int val = 0;
+        for (int i = 0; i < srcsize; i++) {
+            val = ulaw2linear(src[i + start] & 0xFF);
+            decbuffer[2 * i + 1] = (byte)(val >> 8);
+            decbuffer[2 * i] = (byte)(val << 24 >> 24);
+        }
+        return true;
+    }
+
+    public static short[] decodeALaw(byte[] src, int start, int srcsize) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return null;
+        short[] decbuffer = new short[srcsize];
+        for (int i = 0; i < srcsize; i++)
+            decbuffer[i] = (short)alaw2linear(src[i + start] & 0xFF);
+        return decbuffer;
+    }
+
+    public static byte[] decodeALawExt(byte[] src, int start, int srcsize) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return null;
+        byte[] decbuffer = new byte[srcsize * 2];
+        int val = 0;
+        for (int i = 0; i < srcsize; i++) {
+            val = alaw2linear(src[i + start] & 0xFF);
+            decbuffer[2 * i + 1] = (byte)(val >> 8);
+            decbuffer[2 * i] = (byte)(val << 24 >> 24);
+        }
+        return decbuffer;
+    }
+
+    public static boolean decodeALawExt(byte[] src, int start, int srcsize, byte[] decbuffer) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return false;
+        int val = 0;
+        for (int i = 0; i < srcsize; i++) {
+            val = alaw2linear(src[i + start] & 0xFF);
+            decbuffer[2 * i + 1] = (byte)(val >> 8);
+            decbuffer[2 * i] = (byte)(val << 24 >> 24);
+        }
+        return true;
+    }
+
+    public static boolean mixPCMLinear(byte[] src1, byte[] src2, int srcsize, byte[] dest) {
+        if (srcsize <= 0 || src1 == null || src1.length < srcsize ||
+                src2 == null || src2.length < srcsize)
+            return false;
+        int encsize = srcsize / 2;
+        int val = 0;
+        int val_ = 0;
+        int val_final = 0;
+        for (int i = 0; i < encsize; i++) {
+            val = src1[2 * i + 1];
+            val_ = src1[2 * i];
+            val = val << 8 & 0xFFFFFF00;
+            val_ &= 0xFF;
+            val |= val_;
+            val_final = val;
+            val = 0;
+            val_ = 0;
+            val = src2[2 * i + 1];
+            val_ = src2[2 * i];
+            val = val << 8 & 0xFFFFFF00;
+            val_ &= 0xFF;
+            val |= val_;
+            val_final = (int)((val + val_final) / 2.0F);
+            dest[2 * i + 1] = (byte)(val_final >> 8);
+            dest[2 * i] = (byte)(val_final << 24 >> 24);
+        }
+        return true;
+    }
+
+    public static boolean amplitudePCMLinear(byte[] src, int srcsize, int rate) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return false;
+        int encsize = srcsize / 2;
+        int val = 0;
+        int val_ = 0;
+        int val_final = 0;
+        for (int i = 0; i < encsize; i++) {
+            val = src[2 * i + 1];
+            val_ = src[2 * i];
+            val = val << 8 & 0xFFFFFF00;
+            val_ &= 0xFF;
+            val |= val_;
+            val_final = val / 10 * rate;
+            src[2 * i + 1] = (byte)(val_final >> 8);
+            src[2 * i] = (byte)(val_final << 24 >> 24);
+        }
+        return true;
+    }
+
+    public static boolean getPCMLinearComportableNoise(byte[] src, int srcsize) {
+        if (srcsize <= 0 || src == null || src.length < srcsize)
+            return false;
+        int encsize = srcsize / 2;
+        int val_final = 0;
+        int val = 0;
+        for (int i = 0; i < encsize; i++) {
+            val = 1;
+            val_final = Math.abs(val) % 10;
+            if (i % 2 == 1)
+                val_final *= -1;
+            src[2 * i + 1] = (byte)(val_final >> 8);
+            src[2 * i] = (byte)(val_final << 24 >> 24);
+        }
+        return true;
+    }
+}

+ 225 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPHeader.java

@@ -0,0 +1,225 @@
+package bssoft.stack.sip;
+
+import java.util.StringTokenizer;
+
+public class SIPHeader {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public int headerType = SIPStack.SIP_HEADERTYPE_NONE;
+
+    public boolean flag = false;
+
+    public SIPHeader(String message, int headerType) {
+        String compactKeyWord = null;
+        if (message != null) {
+            String keyWord;
+            if (headerType == SIPStack.SIP_HEADERTYPE_ACCEPT) {
+                keyWord = "Accept: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ACCEPTENCODING) {
+                keyWord = "Accept-Encoding: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ACCEPTLANGUAGE) {
+                keyWord = "Accept-Language: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ALERTINFO) {
+                keyWord = "Alert-Info: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ALLOW) {
+                keyWord = "Allow: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ALLOWEVENTS) {
+                keyWord = "Allow-Events: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_AUTHENTICATIONINFO) {
+                keyWord = "Authentication-Info: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_AUTHORIZATION) {
+                keyWord = "Authorization: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CALLID) {
+                keyWord = "Call-ID: ";
+                compactKeyWord = "i: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CALLINFO) {
+                keyWord = "Call-Info: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTACT) {
+                keyWord = "Contact: ";
+                compactKeyWord = "m: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTENTDISPOSITION) {
+                keyWord = "Content-Disposition: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTENTENCODING) {
+                keyWord = "Content-Encoding: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTENTLANGUAGE) {
+                keyWord = "Content-Language: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTENTLENGTH) {
+                keyWord = "Content-Length: ";
+                compactKeyWord = "l: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CONTENTTYPE) {
+                keyWord = "Content-Type: ";
+                compactKeyWord = "c: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_CSEQ) {
+                keyWord = "CSeq: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_DATE) {
+                keyWord = "Date: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_EVENT) {
+                keyWord = "Event: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ERRORINFO) {
+                keyWord = "Error-Info: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_EXPIRES) {
+                keyWord = "Expires: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_FROM) {
+                keyWord = "From: ";
+                compactKeyWord = "f: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_INREPLYTO) {
+                keyWord = "In-Reply-To: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_MAXFORWARDS) {
+                keyWord = "Max-Forwards: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_MINEXPIRES) {
+                keyWord = "Min-Expires: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_MIMEVERSION) {
+                keyWord = "MIME-Version: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ORGANIZATION) {
+                keyWord = "Organization: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PRIORITY) {
+                keyWord = "Priority: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PROXYAUTHENTICATE) {
+                keyWord = "Proxy-Authenticate: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PROXYAUTHORIZATION) {
+                keyWord = "Proxy-Authorization: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PROXYREQUIRE) {
+                keyWord = "Proxy-Require: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_PASSERTEDIDENTITY) {
+                keyWord = "P-Asserted-Identity: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_RECORDROUTE) {
+                keyWord = "Record-Route: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_REPLYTO) {
+                keyWord = "Reply-To: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_REQUIRE) {
+                keyWord = "Require: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_RETRYAFTER) {
+                keyWord = "Retry-After: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_ROUTE) {
+                keyWord = "Route: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_SERVER) {
+                keyWord = "Server: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_SUBJECT) {
+                keyWord = "Subject: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_SUPPORTED) {
+                keyWord = "Supported: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_TIMESTAMP) {
+                keyWord = "Timestamp: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_TO) {
+                keyWord = "To: ";
+                compactKeyWord = "t: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_UNSUPPORTED) {
+                keyWord = "Unsupported: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_USERAGENT) {
+                keyWord = "User-Agent: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_VIA) {
+                keyWord = "Via: ";
+                compactKeyWord = "v: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_WARNING) {
+                keyWord = "Warning: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_WWWAUTHENTICATE) {
+                keyWord = "WWW-Authenticate: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_WwwAUTHENTICATE) {
+                keyWord = "Www-Authenticate: ";
+            } else {
+                keyWord = null;
+            }
+            if (keyWord != null) {
+                int iS = message.indexOf(keyWord);
+                int iE = 0;
+                if (iS >= 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                    if (iE > 0) {
+                        this.header = message.substring(iS, iE);
+                        this.headerValue = message.substring(iS + keyWord.length(), iE);
+                        this.headerType = headerType;
+                        this.flag = true;
+                    }
+                } else {
+                    this.flag = false;
+                }
+            }
+            if (!this.flag && compactKeyWord != null) {
+                int iS = message.indexOf(compactKeyWord);
+                int iE = 0;
+                if (iS >= 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                    if (iE > 0) {
+                        this.header = message.substring(iS, iE);
+                        this.headerValue = message.substring(iS + compactKeyWord.length(), iE);
+                        this.headerType = headerType;
+                        this.flag = true;
+                    }
+                } else {
+                    this.flag = false;
+                }
+            }
+        }
+    }
+
+    public int callSequenceNumber() {
+        int seqCode = 0;
+        if (this.headerType == SIPStack.SIP_HEADERTYPE_CSEQ && this.header != null && this.header.length() > 0) {
+            StringTokenizer tokenArray = new StringTokenizer(this.header, " ", true);
+            int tokenCount = 0;
+            while (tokenArray.hasMoreTokens()) {
+                String token = tokenArray.nextToken();
+                if (token.length() > 0 && token.compareTo(" ") != 0) {
+                    tokenCount++;
+                    if (tokenCount == 2) {
+                        seqCode = Integer.parseInt(token);
+                        break;
+                    }
+                }
+            }
+        }
+        return seqCode;
+    }
+
+    public String getTag() {
+        String tag = null;
+        if ((this.headerType == SIPStack.SIP_HEADERTYPE_FROM || this.headerType == SIPStack.SIP_HEADERTYPE_TO) &&
+                this.header != null && this.header.length() > 0) {
+            StringTokenizer tokenArray = new StringTokenizer(this.header, ";", true);
+            while (tokenArray.hasMoreTokens()) {
+                String token = tokenArray.nextToken();
+                if (token.length() > 0 && token.startsWith("tag=")) {
+                    tag = token.substring(4);
+                    break;
+                }
+            }
+        }
+        return tag;
+    }
+
+    public String getId() {
+        String id = "";
+        if ((this.headerType == SIPStack.SIP_HEADERTYPE_FROM || this.headerType == SIPStack.SIP_HEADERTYPE_TO) &&
+                this.header != null && this.header.length() > 0) {
+            int iS = 0;
+            int iE = 0;
+            iS = this.header.indexOf("sip:");
+            if (iS > 0) {
+                iE = this.header.indexOf("@", iS);
+                if (iE > 0)
+                    id = this.header.substring(iS + 4, iE).trim();
+            }
+        }
+        return id;
+    }
+
+    public String getFieldValue(String fieldName) {
+        if (this.headerValue == null || this.headerValue.length() <= 0)
+            return null;
+        if (fieldName == null || fieldName.length() <= 0)
+            return null;
+        StringTokenizer tokenArray = new StringTokenizer(this.headerValue, ";><", true);
+        String keyWord = String.valueOf(fieldName) + "=";
+        String fieldValue = null;
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken().trim();
+            if (token.length() > 0 && token.startsWith(keyWord)) {
+                fieldValue = token.substring(keyWord.length());
+                break;
+            }
+        }
+        return fieldValue;
+    }
+}

+ 268 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPHeaderParty.java

@@ -0,0 +1,268 @@
+package bssoft.stack.sip;
+
+public class SIPHeaderParty {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public String display = null;
+
+    public String username = null;
+
+    public String sipuri = null;
+
+    public String uriusertag = null;
+
+    public String ip = null;
+
+    public int port = 0;
+
+    public String tag = null;
+
+    public int headerType = SIPStack.SIP_HEADERTYPE_NONE;
+
+    public boolean flag = false;
+
+    public SIPHeaderParty(String message, int headerType) {
+        String compactKeyWord = null;
+        if (message != null) {
+            String keyWord;
+            if (headerType == SIPStack.SIP_HEADERTYPE_FROM) {
+                keyWord = "From: ";
+                compactKeyWord = "f: ";
+            } else if (headerType == SIPStack.SIP_HEADERTYPE_TO) {
+                keyWord = "To: ";
+                compactKeyWord = "t: ";
+            } else {
+                keyWord = null;
+            }
+            if (keyWord != null) {
+                int iS = message.indexOf(keyWord);
+                int iE = 0;
+                if (iS >= 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                    if (iE > 0) {
+                        this.header = message.substring(iS, iE);
+                        this.headerValue = message.substring(iS + keyWord.length(), iE);
+                        this.headerType = headerType;
+                        iE = this.headerValue.indexOf("<sip:");
+                        if (iE > 0) {
+                            String str = null;
+                            str = this.headerValue.substring(0, iE).trim();
+                            if (str != null && str.length() > 1 &&
+                                    str.startsWith("\"") &&
+                                    str.endsWith("\"")) {
+                                this.display = str.substring(1, str.length() - 1);
+                            } else if (str != null && str.length() > 0) {
+                                this.display = str;
+                            }
+                        }
+                        iS = this.headerValue.indexOf("sip:");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(">", iS + 4);
+                            if (iE < 0)
+                                iE = this.headerValue.indexOf(";", iS + 4);
+                            if (iE > 0) {
+                                str = this.headerValue.substring(iS, iE);
+                            } else {
+                                str = this.headerValue.substring(iS);
+                            }
+                            if (str != null && str.length() > 0)
+                                this.sipuri = str.trim();
+                        }
+                        if (this.sipuri != null && this.sipuri.length() > 0) {
+                            iS = this.sipuri.indexOf("@", 4);
+                            if (iS > 0)
+                                this.username = this.sipuri.substring(4, iS).trim();
+                        }
+                        if (this.sipuri != null && this.sipuri.length() > 0) {
+                            iS = this.sipuri.indexOf("@", 4);
+                            String str = null;
+                            if (iS >= 0) {
+                                str = this.sipuri.substring(iS + 1).trim();
+                            } else {
+                                str = this.sipuri.substring(4).trim();
+                            }
+                            this.port = 5060;
+                            if (str != null && str.length() > 0) {
+                                iS = str.indexOf(":");
+                                if (iS > 0) {
+                                    this.port = Integer.parseInt(str.substring(iS + 1).trim());
+                                    this.ip = str.substring(0, iS);
+                                } else {
+                                    this.ip = str;
+                                }
+                            }
+                        }
+                        iS = this.headerValue.indexOf(";tag=");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(";", iS + 5);
+                            if (iE >= 0) {
+                                if (iE > iS + 5) {
+                                    str = this.headerValue.substring(iS + 5, iE);
+                                } else {
+                                    str = "";
+                                }
+                            } else {
+                                str = this.headerValue.substring(iS + 5);
+                            }
+                            if (str != null && str.length() > 0)
+                                this.tag = str.trim();
+                        } else {
+                            this.tag = "";
+                        }
+                        iS = this.headerValue.indexOf("sip:");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(">", iS + 4);
+                            if (iE > 0)
+                                str = this.headerValue.substring(iS, iE);
+                            if (str != null && str.length() > 0) {
+                                iS = str.indexOf(";user=", iS + 4);
+                                if (iS > 0) {
+                                    this.uriusertag = str.substring(iS + 6);
+                                    if (this.uriusertag != null && this.uriusertag.length() > 0 && this.uriusertag.indexOf(";") >= 0)
+                                        if (this.uriusertag.indexOf(";") == 0) {
+                                            this.uriusertag = null;
+                                        } else {
+                                            this.uriusertag = this.uriusertag.substring(0, this.uriusertag.indexOf(";")).trim();
+                                        }
+                                }
+                            }
+                        }
+                        this.flag = true;
+                    }
+                }
+            } else if (compactKeyWord != null) {
+                int iS = message.indexOf(compactKeyWord);
+                int iE = 0;
+                if (iS >= 0) {
+                    iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                    if (iE > 0) {
+                        this.header = message.substring(iS, iE);
+                        this.headerValue = message.substring(iS + compactKeyWord.length(), iE);
+                        this.headerType = headerType;
+                        iE = this.headerValue.indexOf("<sip:");
+                        if (iE > 0) {
+                            String str = null;
+                            str = this.headerValue.substring(0, iE).trim();
+                            if (str != null && str.length() > 1 &&
+                                    str.startsWith("\"") &&
+                                    str.endsWith("\"")) {
+                                this.display = str.substring(1, str.length() - 1);
+                            } else if (str != null && str.length() > 0) {
+                                this.display = str;
+                            }
+                        }
+                        iS = this.headerValue.indexOf("sip:");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(">", iS + 4);
+                            if (iE < 0)
+                                iE = this.headerValue.indexOf(";", iS + 4);
+                            if (iE > 0) {
+                                str = this.headerValue.substring(iS, iE);
+                            } else {
+                                str = this.headerValue.substring(iS);
+                            }
+                            if (str != null && str.length() > 0)
+                                this.sipuri = str.trim();
+                        }
+                        if (this.sipuri != null && this.sipuri.length() > 0) {
+                            iS = this.sipuri.indexOf("@", 4);
+                            if (iS > 0)
+                                this.username = this.sipuri.substring(4, iS).trim();
+                        }
+                        if (this.sipuri != null && this.sipuri.length() > 0) {
+                            iS = this.sipuri.indexOf("@", 4);
+                            String str = null;
+                            if (iS >= 0) {
+                                str = this.sipuri.substring(iS + 1).trim();
+                            } else {
+                                str = this.sipuri.substring(4).trim();
+                            }
+                            this.port = 5060;
+                            if (str != null && str.length() > 0) {
+                                iS = str.indexOf(":");
+                                if (iS > 0) {
+                                    this.port = Integer.parseInt(str.substring(iS + 1).trim());
+                                    this.ip = str.substring(0, iS);
+                                } else {
+                                    this.ip = str;
+                                }
+                            }
+                        }
+                        iS = this.headerValue.indexOf(";tag=");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(";", iS + 5);
+                            if (iE >= 0) {
+                                if (iE > iS + 5) {
+                                    str = this.headerValue.substring(iS + 5, iE);
+                                } else {
+                                    str = "";
+                                }
+                            } else {
+                                str = this.headerValue.substring(iS + 5);
+                            }
+                            if (str != null && str.length() > 0)
+                                this.tag = str.trim();
+                        } else {
+                            this.tag = "";
+                        }
+                        iS = this.headerValue.indexOf("sip:");
+                        if (iS > 0) {
+                            String str = null;
+                            iE = this.headerValue.indexOf(">", iS + 4);
+                            if (iE > 0)
+                                str = this.headerValue.substring(iS, iE);
+                            if (str != null && str.length() > 0) {
+                                iS = str.indexOf(";user=", iS + 4);
+                                if (iS > 0) {
+                                    this.uriusertag = str.substring(iS + 6);
+                                    if (this.uriusertag != null && this.uriusertag.length() > 0 && this.uriusertag.indexOf(";") >= 0)
+                                        if (this.uriusertag.indexOf(";") == 0) {
+                                            this.uriusertag = null;
+                                        } else {
+                                            this.uriusertag = this.uriusertag.substring(0, this.uriusertag.indexOf(";")).trim();
+                                        }
+                                }
+                            }
+                        }
+                        this.flag = true;
+                    }
+                }
+            }
+        }
+    }
+
+    public String getDisplay() {
+        return this.display;
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    public String getSipuri() {
+        return this.sipuri;
+    }
+
+    public String getSipuriusertag() {
+        return this.uriusertag;
+    }
+
+    public String getIp() {
+        return this.ip;
+    }
+
+    public int getPort() {
+        return this.port;
+    }
+
+    public String getTag() {
+        return this.tag;
+    }
+}

+ 135 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPROUTEHeader.java

@@ -0,0 +1,135 @@
+package bssoft.stack.sip;
+
+public class SIPROUTEHeader {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public String username = null;
+
+    public String sipuri = null;
+
+    public String uriusertag = null;
+
+    public String ip = null;
+
+    public int port = 0;
+
+    public String tag = null;
+
+    public boolean flag = false;
+
+    public SIPROUTEHeader(String header) {
+        int iS = 0;
+        int iE = 0;
+        if (header != null && header.length() > 0 && header.startsWith("Route: ")) {
+            this.header = header;
+            this.headerValue = header.substring(7).trim();
+            if (this.headerValue != null && this.headerValue.length() > 0) {
+                iS = this.headerValue.indexOf("sip:");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(">", iS + 4);
+                    if (iE < 0)
+                        iE = this.headerValue.indexOf(";", iS + 4);
+                    if (iE > 0) {
+                        str = this.headerValue.substring(iS, iE);
+                    } else {
+                        str = this.headerValue.substring(iS);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.sipuri = str.trim();
+                }
+                if (this.sipuri != null && this.sipuri.length() > 0) {
+                    iS = this.sipuri.indexOf("@", 4);
+                    if (iS > 0)
+                        this.username = this.sipuri.substring(4, iS).trim();
+                }
+                if (this.sipuri != null && this.sipuri.length() > 0) {
+                    iS = this.sipuri.indexOf("@", 4);
+                    iE = this.sipuri.indexOf(";", 4);
+                    String str = null;
+                    if (iS >= 0 && iE >= 0) {
+                        str = this.sipuri.substring(iS + 1, iE).trim();
+                    } else if (iS >= 0) {
+                        str = this.sipuri.substring(iS + 1).trim();
+                    } else if (iE >= 0) {
+                        str = this.sipuri.substring(4, iE).trim();
+                    } else {
+                        str = this.sipuri.substring(4).trim();
+                    }
+                    this.port = 5060;
+                    if (str != null && str.length() > 0) {
+                        iS = str.indexOf(":");
+                        if (iS > 0) {
+                            this.port = Integer.parseInt(str.substring(iS + 1).trim());
+                            this.ip = str.substring(0, iS);
+                        } else {
+                            this.ip = str;
+                        }
+                    }
+                }
+                iS = this.headerValue.indexOf(";tag=");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(";", iS + 5);
+                    if (iE >= 0) {
+                        if (iE > iS + 5) {
+                            str = this.headerValue.substring(iS + 5, iE);
+                        } else {
+                            str = "";
+                        }
+                    } else {
+                        str = this.headerValue.substring(iS + 5);
+                    }
+                    if (str != null && str.length() > 0)
+                        this.tag = str.trim();
+                }
+                iS = this.headerValue.indexOf("sip:");
+                if (iS > 0) {
+                    String str = null;
+                    iE = this.headerValue.indexOf(">", iS + 4);
+                    if (iE > 0)
+                        str = this.headerValue.substring(iS, iE);
+                    if (str != null && str.length() > 0) {
+                        iS = str.indexOf(";user=", iS + 4);
+                        if (iS > 0) {
+                            this.uriusertag = str.substring(iS + 6);
+                            if (this.uriusertag != null && this.uriusertag.length() > 0 && this.uriusertag.indexOf(";") >= 0)
+                                if (this.uriusertag.indexOf(";") == 0) {
+                                    this.uriusertag = null;
+                                } else {
+                                    this.uriusertag = this.uriusertag.substring(0, this.uriusertag.indexOf(";")).trim();
+                                }
+                        }
+                    }
+                }
+                this.flag = true;
+            }
+        }
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    public String getSipuri() {
+        return this.sipuri;
+    }
+
+    public String getSipuriusertag() {
+        return this.uriusertag;
+    }
+
+    public String getIp() {
+        return this.ip;
+    }
+
+    public int getPort() {
+        return this.port;
+    }
+
+    public String getTag() {
+        return this.tag;
+    }
+}

+ 204 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPRequestLine.java

@@ -0,0 +1,204 @@
+package bssoft.stack.sip;
+
+import android.util.Log;
+
+import java.util.StringTokenizer;
+
+public class SIPRequestLine {
+    public String header = null;
+
+    public int iMethodType = SIPStack.SIP_METHODTYPE_NONE;
+
+    public String uri = null;
+
+    public int version = 2;
+
+    public int revision = 0;
+
+    public int code = 0;
+
+    public int iMessageType = SIPStack.SIP_MSGTYPE_NONE;
+
+    public boolean flag = false;
+
+    public SIPRequestLine(String message) {
+        if (message != null) {
+            StringTokenizer st = new StringTokenizer(message, "\n", true);
+            int headerCount = 0;
+            while (st.hasMoreTokens()) {
+                this.header = st.nextToken();
+                if (this.header.length() > 1) {
+                    if (headerCount == 0 && this.header.startsWith("INVITE") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_INVITE;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("BYE") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_BYE;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("ACK") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_ACK;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("CANCEL") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_CANCEL;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("OPTIONS") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_OPTIONS;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("INFO") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_INFO;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("PRACK") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_PRACK;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("MESSAGE") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_MESSAGE;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("SUBSCRIBE") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_SUBSCRIBE;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("REFER") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_REFER;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("NOTIFY") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_NOTIFY;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("PUBLISH") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_PUBLISH;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("REGISTER") && this.header.endsWith("SIP/2.0\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_REQUEST;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_REGISTER;
+                        this.flag = true;
+                        break;
+                    }
+                    if (headerCount == 0 && this.header.startsWith("SIP/2.0") && this.header.endsWith("\r")) {
+                        this.iMessageType = SIPStack.SIP_MSGTYPE_RESPONSE;
+                        this.iMethodType = SIPStack.SIP_METHODTYPE_NONE;
+                        StringTokenizer tokenArray = new StringTokenizer(this.header, " ", true);
+                        int tokenCount = 0;
+                        //Log.e("INVITEParser", "[INVITEParser] ============ token ============ " + this.header);
+                        String[] strSplit = this.header.split(" ");
+                        this.code = Integer.parseInt(strSplit[1]);
+                        while (tokenArray.hasMoreTokens()) {
+                            String token = tokenArray.nextToken();
+                            //Log.e("INVITEParser", "[INVITEParser] ============ token ============ " + token);
+                            tokenCount++;
+                            if (token.compareTo(" ") != 0 && tokenCount == 2)
+                            //if (tokenCount == 2)
+                                this.code = Integer.parseInt(token);
+                        }
+                        //Log.e("INVITEParser", "[INVITEParser] ============ token  this.code ============ " + this.code);
+                        int iS = message.indexOf("CSeq: ");
+                        int iE = 0;
+                        if (iS >= 0) {
+                            iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                            if (iE <= 0)
+                                break;
+                            String strCSEQ = message.substring(iS, iE);
+                            tokenArray = new StringTokenizer(strCSEQ, " ", true);
+                            tokenCount = 0;
+                            while (tokenArray.hasMoreTokens()) {
+                                String token = tokenArray.nextToken();
+                                if (token.length() > 0 && token.compareTo(" ") != 0) {
+                                    tokenCount++;
+                                    if (tokenCount == 3) {
+                                        if (token.compareTo("REGISTER") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_REGISTER;
+                                        } else if (token.compareTo("INVITE") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_INVITE;
+                                        } else if (token.compareTo("CANCEL") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_CANCEL;
+                                        } else if (token.compareTo("BYE") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_BYE;
+                                        } else if (token.compareTo("INFO") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_INFO;
+                                        } else if (token.compareTo("OPTIONS") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_OPTIONS;
+                                        } else if (token.compareTo("ACK") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_ACK;
+                                        } else if (token.compareTo("REFER") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_REFER;
+                                        } else if (token.compareTo("NOTIFY") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_NOTIFY;
+                                        } else if (token.compareTo("PUBLISH") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_PUBLISH;
+                                        } else if (token.compareTo("MESSAGE") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_MESSAGE;
+                                        } else if (token.compareTo("SUBSCRIBE") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_SUBSCRIBE;
+                                        } else if (token.compareTo("PRACK") == 0) {
+                                            this.iMethodType = SIPStack.SIP_METHODTYPE_PRACK;
+                                        }
+                                        if (this.iMethodType != SIPStack.SIP_METHODTYPE_NONE)
+                                            this.flag = true;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+            if (this.flag && this.iMessageType == SIPStack.SIP_MSGTYPE_REQUEST && this.header != null) {
+                StringTokenizer tokenArray = new StringTokenizer(this.header, " ", true);
+                int tokenCount = 0;
+                while (tokenArray.hasMoreTokens()) {
+                    String token = tokenArray.nextToken();
+                    if (token.compareTo(" ") == 0)
+                        continue;
+                    tokenCount++;
+                    if (tokenCount == 2)
+                        this.uri = token;
+                }
+            }
+        }
+        //print();
+    }
+
+    public void print() {
+        System.out.println("=====================================================");
+        System.out.println("HEADER:");
+        System.out.println(this.header);
+        System.out.println(".....................................................");
+        System.out.println("flag\t\t:" + this.flag);
+        System.out.println("iMethodType\t:" + this.iMethodType);
+        System.out.println("uri\t\t\t:" + this.uri);
+        System.out.println("code\t\t:" + this.code);
+        System.out.println("version\t\t:" + this.version);
+        System.out.println("revision\t:" + this.revision);
+        System.out.println("iMessageType:" + this.iMessageType);
+        System.out.println("=====================================================");
+    }
+}

+ 248 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPSdp.java

@@ -0,0 +1,248 @@
+package bssoft.stack.sip;
+
+import java.util.Date;
+
+public class SIPSdp {
+    public String vH = null;
+
+    public String oH = null;
+
+    public String sH = null;
+
+    public String cH = null;
+
+    public String tH = null;
+
+    public SDPMedia audioM = null;
+
+    public SDPMedia videoM = null;
+
+    public String body = null;
+
+    public String dn = null;
+
+    public String platformIp = null;
+
+    public String audioDescription = null;
+
+    public String videoDescription = null;
+
+    public boolean flag;
+
+    public SIPSdp(String dn, String localIp) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        this.dn = dn;
+        this.platformIp = localIp;
+        long ltime = (new Date()).getTime();
+        this.vH = "v=0" + SIPStack.SIP_LINE_END;
+        this.oH = "o=" + dn + " " + ltime + " " + (ltime + 1L) + " IN IP4 " + this.platformIp + SIPStack.SIP_LINE_END;
+        this.sH = "s=Smart Android call" + SIPStack.SIP_LINE_END;
+        this.cH = "c=IN IP4 " + this.platformIp + SIPStack.SIP_LINE_END;
+        this.tH = "t=0 0" + SIPStack.SIP_LINE_END;
+        this.audioDescription = "";
+        this.videoDescription = "";
+        this.flag = true;
+    }
+
+    public SIPSdp(String dn, String localIp, String localSdpIp) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        this.dn = dn;
+        this.platformIp = localIp;
+        long ltime = (new Date()).getTime();
+        this.vH = "v=0" + SIPStack.SIP_LINE_END;
+        this.oH = "o=" + dn + " " + ltime + " " + (ltime + 1L) + " IN IP4 " + localSdpIp + SIPStack.SIP_LINE_END;
+        this.sH = "s=Smart Android call" + SIPStack.SIP_LINE_END;
+        this.cH = "c=IN IP4 " + localSdpIp + SIPStack.SIP_LINE_END;
+        this.tH = "t=0 0" + SIPStack.SIP_LINE_END;
+        this.audioDescription = "";
+        this.videoDescription = "";
+        this.flag = true;
+    }
+
+    public SIPSdp(String body) {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    //System.exit(0);
+        }
+        if (body != null && body.length() > 0) {
+            this.body = body;
+            int iS = 0;
+            int iE = 0;
+            iS = body.indexOf("v=");
+            if (iS >= 0)
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+            if (iS >= 0 && iE > iS)
+                this.vH = body.substring(iS, iE + 2);
+            iS = 0;
+            iE = 0;
+            iS = body.indexOf("o=");
+            if (iS >= 0)
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+            if (iS >= 0 && iE > iS)
+                this.oH = body.substring(iS, iE + 2);
+            iS = 0;
+            iE = 0;
+            iS = body.indexOf("s=");
+            if (iS >= 0)
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+            if (iS >= 0 && iE > iS)
+                this.sH = body.substring(iS, iE + 2);
+            iS = 0;
+            iE = 0;
+            iS = body.indexOf("c=");
+            if (iS >= 0)
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+            if (iS >= 0 && iE > iS)
+                this.cH = body.substring(iS, iE + 2);
+            iS = 0;
+            iE = 0;
+            iS = body.indexOf("t=");
+            if (iS >= 0)
+                iE = body.indexOf(SIPStack.SIP_LINE_END, iS);
+            if (iS >= 0 && iE > iS)
+                this.tH = body.substring(iS, iE + 2);
+            if (this.vH != null && this.vH.length() > 0 &&
+                    this.oH != null && this.oH.length() > 0 &&
+                    this.tH != null && this.tH.length() > 0) {
+                this.platformIp = "0.0.0.0";
+                if (this.cH != null && this.cH.length() > 0 && this.cH.startsWith("c=IN IP4 ")) {
+                    iE = this.cH.indexOf(SIPStack.SIP_LINE_END);
+                    this.platformIp = this.cH.substring("c=IN IP4 ".length(), iE);
+                }
+                iS = body.indexOf("m=audio ");
+                if (iS > 0) {
+                    iE = body.indexOf("m=", iS + 8);
+                    if (iE > 0 && iE > iS) {
+                        this.audioM = new SDPMedia(body.substring(iS, iE), this.platformIp);
+                    } else if (iE < 0) {
+                        this.audioM = new SDPMedia(body.substring(iS), this.platformIp);
+                    }
+                }
+                iS = body.indexOf("m=video ");
+                if (iS > 0) {
+                    iE = body.indexOf("m=", iS + 8);
+                    if (iE > 0 && iE > iS) {
+                        this.videoM = new SDPMedia(body.substring(iS, iE), this.platformIp);
+                    } else if (iE < 0) {
+                        this.videoM = new SDPMedia(body.substring(iS), this.platformIp);
+                    }
+                }
+            }
+            this.flag = true;
+        }
+    }
+
+    public boolean setMediaPort(int mediaType, int port) {
+        if (mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            if (this.audioM == null) {
+                this.audioM = new SDPMedia(mediaType);
+                if (this.audioM != null && this.audioM.flag)
+                    return this.audioM.setMediaAddress(this.platformIp, port);
+            }
+        } else if (mediaType == SIPStack.SIP_MEDIATYPE_VIDEO) {
+            if (this.videoM == null) {
+                this.videoM = new SDPMedia(mediaType);
+                if (this.videoM != null && this.videoM.flag)
+                    return this.videoM.setMediaAddress(this.platformIp, port);
+            }
+        }
+        return false;
+    }
+
+    public boolean setCodec(int mediaType, int codec) {
+        if (mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            if (this.audioM != null && this.audioM.flag)
+                return this.audioM.setCodec(codec);
+        } else if (mediaType == SIPStack.SIP_MEDIATYPE_VIDEO) {
+            if (this.videoM != null && this.videoM.flag)
+                return this.videoM.setCodec(codec);
+        }
+        return false;
+    }
+
+    public boolean setCodec(int mediaType, int codec, String describe) {
+        if (mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            if (this.audioM != null && this.audioM.flag)
+                return this.audioM.setCodec(codec, describe);
+        } else if (mediaType == SIPStack.SIP_MEDIATYPE_VIDEO) {
+            if (this.videoM != null && this.videoM.flag)
+                return this.videoM.setCodec(codec, describe);
+        }
+        return false;
+    }
+
+    public boolean setFmtpDescribe(int mediaType, int codec, String describe) {
+        if (mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
+            if (this.audioM != null && this.audioM.flag)
+                return this.audioM.setFmtpDescribe(codec, describe);
+        } else if (mediaType == SIPStack.SIP_MEDIATYPE_VIDEO) {
+            if (this.videoM != null && this.videoM.flag)
+                return this.videoM.setFmtpDescribe(codec, describe);
+        }
+        return false;
+    }
+
+    public void resetSdp() {
+        this.flag = false;
+    }
+
+    public String getBodyString() {
+        this.audioDescription = "";
+        this.videoDescription = "";
+        if (!this.flag)
+            return null;
+        if (this.audioM != null && this.audioM.flag) {
+            this.audioDescription = this.audioM.getMediaString();
+            if (this.audioDescription == null)
+                this.audioDescription = "";
+        }
+        if (this.videoM != null && this.videoM.flag) {
+            this.videoDescription = this.videoM.getMediaString();
+            if (this.videoDescription == null)
+                this.videoDescription = "";
+        }
+        this.body = String.valueOf(this.vH) +
+                this.oH +
+                this.sH +
+                this.cH +
+                this.tH +
+                this.audioDescription +
+                this.videoDescription;
+        return this.body;
+    }
+
+    public String getFinalBodyString() {
+        this.audioDescription = "";
+        this.videoDescription = "";
+        if (!this.flag)
+            return null;
+        if (this.audioM != null && this.audioM.flag) {
+            this.audioDescription = this.audioM.getFinalMediaString();
+            if (this.audioDescription == null)
+                this.audioDescription = "";
+        }
+        if (this.videoM != null && this.videoM.flag) {
+            this.videoDescription = this.videoM.getFinalMediaString();
+            if (this.videoDescription == null)
+                this.videoDescription = "";
+        }
+        this.body = String.valueOf(this.vH) +
+                this.oH +
+                this.sH +
+                this.cH +
+                this.tH +
+                this.audioDescription +
+                this.videoDescription;
+        return this.body;
+    }
+
+    public boolean update(String body) {
+        return true;
+    }
+}

+ 785 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPStack.java

@@ -0,0 +1,785 @@
+package bssoft.stack.sip;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+public class SIPStack {
+    public static int SIP_LOCAL_PORT = 5060;
+
+    public static int SIP_SIGNAL_PORT = 5060;
+
+    public static int MAX_SIGNAL_PORTS = 100;
+
+    public static int SIP_METHODTYPE_NONE = 0;
+
+    public static int SIP_METHODTYPE_REGISTER = 1;
+
+    public static int SIP_METHODTYPE_INVITE = 2;
+
+    public static int SIP_METHODTYPE_CANCEL = 3;
+
+    public static int SIP_METHODTYPE_BYE = 4;
+
+    public static int SIP_METHODTYPE_INFO = 5;
+
+    public static int SIP_METHODTYPE_OPTIONS = 6;
+
+    public static int SIP_METHODTYPE_ACK = 7;
+
+    public static int SIP_METHODTYPE_REFER = 8;
+
+    public static int SIP_METHODTYPE_NOTIFY = 9;
+
+    public static int SIP_METHODTYPE_MESSAGE = 10;
+
+    public static int SIP_METHODTYPE_SUBSCRIBE = 11;
+
+    public static int SIP_METHODTYPE_PRACK = 12;
+
+    public static int SIP_METHODTYPE_PUBLISH = 13;
+
+    public static int SIP_METHODTYPE_RESPONSE = 14;
+
+    public static int SIP_HEADERTYPE_NONE = 0;
+
+    public static int SIP_HEADERTYPE_ACCEPT = 1;
+
+    public static int SIP_HEADERTYPE_ACCEPTENCODING = 2;
+
+    public static int SIP_HEADERTYPE_ACCEPTLANGUAGE = 3;
+
+    public static int SIP_HEADERTYPE_ALERTINFO = 4;
+
+    public static int SIP_HEADERTYPE_ALLOW = 5;
+
+    public static int SIP_HEADERTYPE_ALLOWEVENTS = 6;
+
+    public static int SIP_HEADERTYPE_AUTHENTICATIONINFO = 7;
+
+    public static int SIP_HEADERTYPE_AUTHORIZATION = 8;
+
+    public static int SIP_HEADERTYPE_CALLID = 9;
+
+    public static int SIP_HEADERTYPE_CALLINFO = 10;
+
+    public static int SIP_HEADERTYPE_CONTACT = 11;
+
+    public static int SIP_HEADERTYPE_CONTENTDISPOSITION = 12;
+
+    public static int SIP_HEADERTYPE_CONTENTENCODING = 13;
+
+    public static int SIP_HEADERTYPE_CONTENTLANGUAGE = 14;
+
+    public static int SIP_HEADERTYPE_CONTENTLENGTH = 15;
+
+    public static int SIP_HEADERTYPE_CONTENTTYPE = 16;
+
+    public static int SIP_HEADERTYPE_CSEQ = 17;
+
+    public static int SIP_HEADERTYPE_DATE = 18;
+
+    public static int SIP_HEADERTYPE_EVENT = 19;
+
+    public static int SIP_HEADERTYPE_ERRORINFO = 20;
+
+    public static int SIP_HEADERTYPE_EXPIRES = 21;
+
+    public static int SIP_HEADERTYPE_FROM = 22;
+
+    public static int SIP_HEADERTYPE_INREPLYTO = 23;
+
+    public static int SIP_HEADERTYPE_MAXFORWARDS = 24;
+
+    public static int SIP_HEADERTYPE_MINEXPIRES = 25;
+
+    public static int SIP_HEADERTYPE_MIMEVERSION = 26;
+
+    public static int SIP_HEADERTYPE_ORGANIZATION = 27;
+
+    public static int SIP_HEADERTYPE_PRIORITY = 28;
+
+    public static int SIP_HEADERTYPE_PROXYAUTHENTICATE = 29;
+
+    public static int SIP_HEADERTYPE_PROXYAUTHORIZATION = 30;
+
+    public static int SIP_HEADERTYPE_PROXYREQUIRE = 31;
+
+    public static int SIP_HEADERTYPE_PASSERTEDIDENTITY = 32;
+
+    public static int SIP_HEADERTYPE_RECORDROUTE = 33;
+
+    public static int SIP_HEADERTYPE_REPLYTO = 34;
+
+    public static int SIP_HEADERTYPE_REQUIRE = 35;
+
+    public static int SIP_HEADERTYPE_RETRYAFTER = 36;
+
+    public static int SIP_HEADERTYPE_ROUTE = 37;
+
+    public static int SIP_HEADERTYPE_SERVER = 38;
+
+    public static int SIP_HEADERTYPE_SUBJECT = 39;
+
+    public static int SIP_HEADERTYPE_SUPPORTED = 40;
+
+    public static int SIP_HEADERTYPE_TIMESTAMP = 41;
+
+    public static int SIP_HEADERTYPE_TO = 42;
+
+    public static int SIP_HEADERTYPE_UNSUPPORTED = 43;
+
+    public static int SIP_HEADERTYPE_USERAGENT = 44;
+
+    public static int SIP_HEADERTYPE_VIA = 45;
+
+    public static int SIP_HEADERTYPE_WARNING = 46;
+
+    public static int SIP_HEADERTYPE_WWWAUTHENTICATE = 47;
+
+    public static int SIP_HEADERTYPE_WwwAUTHENTICATE = 48;
+
+    public static String SIP_LINE_END = "\r\n";
+
+    public static String SIP_LINE_DOUBLEEND = "\r\n\r\n";
+
+    public static String SIP_LINE_END_SINGLE = "\n";
+
+    public static String USER_AGENT = "BSSHns release 0100o";
+
+    public static int SIP_MSGTYPE_NONE = 0;
+
+    public static int SIP_MSGTYPE_REQUEST = 1;
+
+    public static int SIP_MSGTYPE_RESPONSE = 2;
+
+    public static int SIP_REGSTATE_IDLE = 0;
+
+    public static int SIP_REGSTATE_REGISTERING = 1;
+
+    public static int SIP_REGSTATE_REGISTERED = 2;
+
+    public static int SIP_REGSTATE_UNREGISTERING = 3;
+
+    public static int SIP_REGSTATE_AUTHORIZING = 4;
+
+    public static int SIP_REGSTATE_UNAUTHORIZED = 5;
+
+    public static int SIP_REGSTATE_UNAVAILABLE = 6;
+
+    public static final int SIP_CALLSTATE_IDLE = 0;
+
+    public static final int SIP_CALLSTATE_INVITING = 1;
+
+    public static final int SIP_CALLSTATE_OFFERRED = 2;
+
+    public static final int SIP_CALLSTATE_PROCEEDING = 3;
+
+    public static final int SIP_CALLSTATE_PROGRESSING = 4;
+
+    public static final int SIP_CALLSTATE_ACCEPTED = 5;
+
+    public static final int SIP_CALLSTATE_REMOTEACCEPTED = 6;
+
+    public static final int SIP_CALLSTATE_CONNECTED = 7;
+
+    public static final int SIP_CALLSTATE_DISCONNECTING = 8;
+
+    public static final int SIP_CALLSTATE_TERMINATING = 9;
+
+    public static final int SIP_CALLSTATE_UNAUTHORIZED = 10;
+
+    public static final int SIP_CALLSTATE_CANCELLING = 11;
+
+    public static final int SIP_CALLSTATE_CANCELLED = 12;
+
+    public static final int SIP_CALLSTATE_RECANCELLING = 13;
+
+    public static final int SIP_CALLSTATE_CANCELREMOTEACCEPTED = 14;
+
+    public static final int SIP_CALLSTATE_REJECTED = 15;
+
+    public static final int SIP_CALLSTATE_REDIRECTED = 16;
+
+    public static final int SIP_CALLSTATE_UPDATING = 20;
+
+    public static final int SIP_CALLSTATE_UPDATEPROCEEDING = 21;
+
+    public static final int SIP_CALLSTATE_UPDATEPROGRESSING = 22;
+
+    public static final int SIP_CALLSTATE_UPDATEOFFERRED = 23;
+
+    public static final int SIP_CALLSTATE_UPDATEACCEPTED = 24;
+
+    public static final int SIP_CALLSTATE_UPDATEREJECTED = 25;
+
+    public static final int SIP_CALLSTATE_UPDATEREMOTEACCEPTED = 26;
+
+    public static final int SIP_CALLSTATE_UPDATEREMOTEREJECTED = 27;
+
+    public static final int SIP_CALLSTATE_UPDATEUNAUTHORIZED = 28;
+
+    public static final int SIP_CALLSTATE_UPDATEREDIRECTED = 29;
+
+    public static int SIP_CALLMODE_NONE = 0;
+
+    public static int SIP_CALLMODE_BASIC = 1;
+
+    public static int SIP_CALLMODE_HOLD = 2;
+
+    public static int SIP_SERVICEMODE_BASIC = 0;
+
+    public static int SIP_SERVICEMODE_CONFERENCE = 1;
+
+    public static int SIP_CALLDIRECTION_NONE = 0;
+
+    public static int SIP_CALLDIRECTION_IN = 1;
+
+    public static int SIP_CALLDIRECTION_OUT = 2;
+
+    public static int SIP_MEDIATYPE_NONE = 0;
+
+    public static int SIP_MEDIATYPE_AUDIO = 1;
+
+    public static int SIP_MEDIATYPE_VIDEO = 2;
+
+    public static int SIP_CODEC_NONE = -1;
+
+    public static int SIP_CODEC_G711U = 0;
+
+    public static int SIP_CODEC_G711A = 8;
+
+    public static int SIP_CODEC_G7231 = 4;
+
+    public static int SIP_CODEC_G729 = 18;
+
+    public static int SIP_CODEC_H263 = 34;
+
+    public static int SIP_CODEC_H264 = 98;
+
+    public static int PRIMARY_CODEC_AUDIO = SIP_CODEC_G711U;
+
+    public static int PRIMARY_CODEC_VIDEO = SIP_CODEC_H263;
+
+    public static int SIP_DTMFINFO_DTMFRELAY = 0;
+
+    public static int SIP_DTMFINFO_DTMF = 1;
+
+    public static int SIP_SEQUENCE_INVITE = 1;
+
+    public static int SIP_SEQUENCE_REGISTER = 1;
+
+    public static int SIP_MEDIA_INITPORT = 3000;
+
+    public static int SIP_MEDIA_PORTS = 5;
+
+    public static int SIP_MEDIAFLOW_NONE = 0;
+
+    public static int SIP_MEDIAFLOW_SENDRECV = 1;
+
+    public static int SIP_MEDIAFLOW_SENDONLY = 2;
+
+    public static int SIP_MEDIAFLOW_RECVONLY = 3;
+
+    public static int RTP_AUDIO_SIZE = 1024;
+
+    public static int RTP_VIDEO_SIZE = 30000;
+
+    public static boolean[] SIP_MEDIA_PORTFLAG = new boolean[SIP_MEDIA_PORTS];
+
+    public static int CS_TIMEOUT_TI = 3;
+
+    public static int CS_TIMEOUT_T0 = 15;
+
+    public static int CS_TIMEOUT_T00 = 10;
+
+    public static int CS_TIMEOUT_T000 = 5;
+
+    public static int CS_TIMEOUT_T1 = 30;
+
+    public static int CS_TIMEOUT_T2 = 120;
+
+    public static int CS_TIMEOUT_T3 = 7;
+
+    public static int CS_TIMEOUT_T4 = 7200;
+
+    public static int CS_TIMEOUT_T5 = 7;
+
+    public static int CS_TIMEOUT_T6 = 0;
+
+    public static int CS_TIMEOUT_T7 = 30;
+
+    public static int CS_TIMEOUT_T8 = 7;
+
+    public static int CS_TIMEOUT_T80 = 2;
+
+    public static int CS_TIMEOUT_RESPONSE = 1;
+
+    public static int NETWORKIF_CHECK_TIME = 5;
+
+    public static int TEARDOWN_CODE_NORMAL = 0;
+
+    public static int TEARDOWN_CODE_EEREJECT = 1;
+
+    public static int TEARDOWN_CODE_ERREJECT = 2;
+
+    public static int TEARDOWN_CODE_NOTFOUND = 3;
+
+    public static int TEARDOWN_CODE_ERROR = 4;
+
+    public static int SIP_NETIF_UNAVAILABLE = 0;
+
+    public static int SIP_NETIF_AVAILABLE = 1;
+
+    public static int SIP_NETIF_UNREACHABLE = 2;
+
+    public static int REPEAT_SENDCOUNT = 3;
+
+    public static int SIP_MAXMESSAGE_SIZE = 2500;
+
+    public static boolean SIP_MESSAGE_DEBUG = false;
+
+    public static boolean SIP_CALLHANDLE_DEBUG = false;
+
+    public static Date bootTime = new Date();
+
+    public static int exceptionCountAtCurrentCall = 0;
+
+    public static boolean ventureCall = true;
+
+    public static boolean bLimitedUse = false;
+
+    public static int BACKGROUNDIDLE_MAX_SECONDS = 28800;
+
+    public static int networkStatus = SIP_NETIF_UNAVAILABLE;
+
+    public static String generalPhoneNumber = "";
+
+    public static String hwModelName = "";
+
+    public static String hwId = "";
+
+    public static String firmVersion = "";
+
+    public static String hwImsi = "";
+
+    public static String hwImei = "";
+
+    public static String gcmRegistId = "";
+
+    public static boolean bGCMRegistSend = false;
+
+    public static String ANDROID_API_KEY = "AIzaSyDZcNyOPs5iTQ9kGZaF56Ngf4eCQDzMEl0";
+
+    public static boolean isInternetWiMax = false;
+
+    public static boolean isInternetWiFi = false;
+
+    public static boolean isInternetMobile = false;
+
+    public static String localSdpIp = "0.0.0.0";
+
+    public static boolean usePrivateWiMax = true;
+
+    public static boolean bShutdownApplication = false;
+
+    public static boolean bOuttraffic = false;
+
+    public static boolean bIntraffic = false;
+
+    public static String macAddress = "";
+
+    public static boolean bTtsservice = false;
+
+    public static boolean bSupportTts = false;
+
+    public static int WIFI_CALL_SIGNAL_MIN = 3;
+
+    public static Date networkInfoCheckTime = new Date();
+
+    public static int WIFI_SIGNAL_VALUE = 0;
+
+    public static String mobileLanguage = "ko";
+
+    public static boolean bActive = false;
+
+    public static boolean bVibrator = true;
+
+    public static boolean bVibrating = false;
+
+    public static int iVibrator = 0;
+
+    public static GetIpDns ipdns = new GetIpDns();
+
+    public static boolean bNetworkActive = false;
+
+    public static int antenaOnStep = 0;
+
+    public static boolean bProximityOn = false;
+
+    public static int localPort = SIP_LOCAL_PORT;
+
+    public static String strLocalip = null;
+
+    public static boolean bBackgroundRunning = false;
+
+    public static boolean bGeneralPhoneDetected = false;
+
+    public static stackKey stackkey = new stackKey();
+
+    public static Date backgroundEnteredTime = new Date();
+
+    public static boolean bdialContextActive = false;
+
+    public static UserDial userDial = new UserDial();
+
+    public static int SIPCTRL_INTERVAL = 40;
+
+    public static boolean bVideocommunication = true;
+
+    public static boolean bDirectCall = true;
+
+    protected static boolean bStackLicensed = false;
+
+    public static boolean bUseSendTimer = false;
+
+    public static boolean bUseCtrlTimer = false;
+
+    public static int getCSeqMethod(String s) {
+        int iMethodType = SIP_METHODTYPE_NONE;
+        int iS = s.indexOf("CSeq: ");
+        int iE = 0;
+        if (iS >= 0)
+            iE = s.indexOf(SIP_LINE_END, iS);
+        if (iE <= 0)
+            return iMethodType;
+        String strCSEQ = s.substring(iS, iE);
+        StringTokenizer tokenArray = new StringTokenizer(strCSEQ, " ", true);
+        int tokenCount = 0;
+        while (tokenArray.hasMoreTokens()) {
+            String token = tokenArray.nextToken();
+            if (token.length() > 0 && token.compareTo(" ") != 0) {
+                tokenCount++;
+                if (tokenCount == 3) {
+                    if (token.compareTo("REGISTER") == 0) {
+                        iMethodType = SIP_METHODTYPE_REGISTER;
+                        break;
+                    }
+                    if (token.compareTo("INVITE") == 0) {
+                        iMethodType = SIP_METHODTYPE_INVITE;
+                        break;
+                    }
+                    if (token.compareTo("CANCEL") == 0) {
+                        iMethodType = SIP_METHODTYPE_CANCEL;
+                        break;
+                    }
+                    if (token.compareTo("BYE") == 0) {
+                        iMethodType = SIP_METHODTYPE_BYE;
+                        break;
+                    }
+                    if (token.compareTo("INFO") == 0) {
+                        iMethodType = SIP_METHODTYPE_INFO;
+                        break;
+                    }
+                    if (token.compareTo("OPTIONS") == 0) {
+                        iMethodType = SIP_METHODTYPE_OPTIONS;
+                        break;
+                    }
+                    if (token.compareTo("ACK") == 0) {
+                        iMethodType = SIP_METHODTYPE_ACK;
+                        break;
+                    }
+                    if (token.compareTo("REFER") == 0) {
+                        iMethodType = SIP_METHODTYPE_REFER;
+                        break;
+                    }
+                    if (token.compareTo("NOTIFY") == 0) {
+                        iMethodType = SIP_METHODTYPE_NOTIFY;
+                        break;
+                    }
+                    if (token.compareTo("MESSAGE") == 0) {
+                        iMethodType = SIP_METHODTYPE_MESSAGE;
+                        break;
+                    }
+                    if (token.compareTo("SUBSCRIBE") == 0) {
+                        iMethodType = SIP_METHODTYPE_SUBSCRIBE;
+                        break;
+                    }
+                    if (token.compareTo("PRACK") == 0)
+                        iMethodType = SIP_METHODTYPE_PRACK;
+                    break;
+                }
+            }
+        }
+        return iMethodType;
+    }
+
+    public static int getRequestlineMethod(String str) {
+        int iMethodType = SIP_METHODTYPE_NONE;
+        if (str.startsWith("INVITE") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_INVITE;
+        } else if (str.startsWith("BYE") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_BYE;
+        } else if (str.startsWith("ACK") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_ACK;
+        } else if (str.startsWith("CANCEL") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_CANCEL;
+        } else if (str.startsWith("OPTIONS") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_OPTIONS;
+        } else if (str.startsWith("INFO") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_INFO;
+        } else if (str.startsWith("PRACK") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_PRACK;
+        } else if (str.startsWith("MESSAGE") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_MESSAGE;
+        } else if (str.startsWith("SUBSCRIBE") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_SUBSCRIBE;
+        } else if (str.startsWith("REFER") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_REFER;
+        } else if (str.startsWith("NOTIFY") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_NOTIFY;
+        } else if (str.startsWith("REGISTER") && str.endsWith("SIP/2.0\r")) {
+            iMethodType = SIP_METHODTYPE_REGISTER;
+        } else if (str.startsWith("SIP/2.0") && str.endsWith("\r")) {
+            iMethodType = SIP_METHODTYPE_RESPONSE;
+        }
+        return iMethodType;
+    }
+
+    public static void setLicense(String strLicense) {
+        if (bLimitedUse) {
+            Date currentDate = new Date();
+            int month = currentDate.getMonth() + 1;
+            int day = currentDate.getDate();
+            int year = currentDate.getYear() + 1900;
+            if (year != 2014 || month > 12) {
+                System.out.println("사용기간 종료되었습니다.");
+                        bStackLicensed = false;
+                System.exit(0);
+            }
+        }
+        String license = "주식회사아이콘트롤스 200701243005451";
+        if (strLicense.compareTo(license) == 0) {
+            bStackLicensed = true;
+        } else {
+            System.out.println("SIP 라이슨스가 맞지 않습니다.");
+                    bStackLicensed = false;
+        }
+        System.out.println(
+                "이 스택은 아이콘트롤스 홈네트워크용입니다.");
+    }
+
+    public static String getResponseDescription(int code) {
+        switch (code) {
+            case 100:
+                return "Trying";
+            case 180:
+                return "Ringing";
+            case 181:
+                return "Call Is Being Forwarded";
+            case 182:
+                return "Call Queued";
+            case 183:
+                return "Session Progress";
+            case 200:
+                return "OK";
+            case 300:
+                return "Multiple Choices";
+            case 301:
+                return "Moved Permanently";
+            case 302:
+                return "Moved Temporarily";
+            case 305:
+                return "Use Proxy";
+            case 380:
+                return "Alternative Service";
+            case 400:
+                return "Bad Request";
+            case 401:
+                return "Unauthorized";
+            case 402:
+                return "Payment Required";
+            case 403:
+                return "Forbidden";
+            case 404:
+                return "Not Found";
+            case 405:
+                return "Method Not Allowed";
+            case 406:
+                return "Not Acceptable";
+            case 407:
+                return "Proxy Authentication Required";
+            case 408:
+                return "Request Timeout";
+            case 409:
+                return "Conflict";
+            case 410:
+                return "Gone";
+            case 411:
+                return "Length Required";
+            case 413:
+                return "Request Entity Too Large";
+            case 414:
+                return "Request-URI Too Long";
+            case 415:
+                return "Unsupported Media Type";
+            case 420:
+                return "Bad Extension";
+            case 421:
+                return "Extension Required";
+            case 423:
+                return "Interval Too Brief";
+            case 480:
+                return "Temporarily Unavailable";
+            case 481:
+                return "Call Leg Does Not Exist";
+            case 482:
+                return "Loop Detected";
+            case 483:
+                return "Two Many Hops";
+            case 484:
+                return "Address Incomplete";
+            case 485:
+                return "Ambiguous";
+            case 486:
+                return "Busy Here";
+            case 487:
+                return "Request Canceled";
+            case 488:
+                return "Not Acceptable Here";
+            case 500:
+                return "Server Internal Error";
+            case 501:
+                return "Not Implemented";
+            case 502:
+                return "Bad Gateway";
+            case 503:
+                return "Service Unavailable";
+            case 504:
+                return "Gateway Timeout";
+            case 505:
+                return "Version Not Supported";
+            case 600:
+                return "Busy Everywhere";
+            case 603:
+                return "Decline";
+            case 604:
+                return "Does Not Exist Anywhere";
+            case 606:
+                return "Not Acceptable";
+        }
+        return "";
+    }
+
+    public static String BSSMD5Get(String data) {
+        if (data == null || data.length() <= 0)
+            return null;
+        try {
+            SIPmd5 md = SIPmd5.getInstance();
+            return md.hashData(data.getBytes());
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace(System.out);
+            exceptionCountAtCurrentCall++;
+            return null;
+        }
+    }
+
+    public static String getViaBranch() {
+        Date today = new Date();
+        return "z9hG4bK-" + today.getTime() + "-" + ((int)today.getTime() % 7);
+    }
+
+    public static String newTag(String prefix) {
+        Date today = new Date();
+        return String.valueOf(prefix) + today.getTime() + "-" + today.hashCode();
+    }
+
+    public static String newTag() {
+        Date today = new Date();
+        return String.valueOf(today.getTime()) + "." + today.hashCode();
+    }
+
+    public static int getFreeAudioRtpPort() {
+        for (int i = 0; i < SIP_MEDIA_PORTS; i++) {
+            if (!SIP_MEDIA_PORTFLAG[i]) {
+                SIP_MEDIA_PORTFLAG[i] = true;
+                return SIP_MEDIA_INITPORT + i * 2;
+            }
+        }
+        return 0;
+    }
+
+    public static boolean freeAudioRtpPort(int port) {
+        int index = (port - SIP_MEDIA_INITPORT) / 2;
+        if (index >= 0 && index < SIP_MEDIA_PORTS) {
+            SIP_MEDIA_PORTFLAG[index] = false;
+            return true;
+        }
+        return false;
+    }
+
+    public static void printAudioRtpPortInfo() {
+        System.out.print(">>>> RTP PORT STATUS  ");
+        for (int i = 0; i < SIP_MEDIA_PORTS; i++)
+            System.out.print("  " + SIP_MEDIA_PORTFLAG[i]);
+        System.out.println("  ");
+    }
+
+    public static String getIPV4(String host) {
+        if (host == null || host.length() == 0)
+            return null;
+        String ip = null;
+        try {
+            InetAddress ia = InetAddress.getByName(host);
+            byte[] address = ia.getAddress();
+            if (address.length == 4) {
+                int unsignedByte1 = (address[0] < 0) ? (address[0] + 256) : address[0];
+                int unsignedByte2 = (address[1] < 0) ? (address[1] + 256) : address[1];
+                int unsignedByte3 = (address[2] < 0) ? (address[2] + 256) : address[2];
+                int unsignedByte4 = (address[3] < 0) ? (address[3] + 256) : address[3];
+                ip = String.valueOf(unsignedByte1) + "." + unsignedByte2 + "." + unsignedByte3 + "." + unsignedByte4;
+            }
+        } catch (UnknownHostException uhe) {
+            System.err.println(uhe);
+            exceptionCountAtCurrentCall++;
+        } catch (Exception e) {
+            System.err.println(e);
+        }
+        return ip;
+    }
+
+    public static boolean isPrivateIp(String ip) {
+        if (ip == null || ip.length() < 7)
+            return false;
+        boolean bPrivate = false;
+        StringTokenizer st = new StringTokenizer(ip, ".", true);
+        int tokenCount = 0;
+        String token = null;
+        int ipdigit_0 = 0;
+        int ipdigit_1 = 0;
+        while (st.hasMoreTokens()) {
+            token = st.nextToken().trim();
+            if (token != null && token.length() > 0 &&
+                    token.length() <= 3 &&
+                    token.compareTo(".") != 0) {
+                if (tokenCount == 0) {
+                    ipdigit_0 = Integer.parseInt(token.trim());
+                } else if (tokenCount == 1) {
+                    ipdigit_1 = Integer.parseInt(token.trim());
+                }
+                tokenCount++;
+            }
+        }
+        if (tokenCount == 4)
+            bPrivate = !(ipdigit_0 != 10 && (
+                    ipdigit_0 != 172 || ipdigit_1 < 16 || ipdigit_1 > 31) && (
+                    ipdigit_0 != 192 || ipdigit_1 != 168));
+        return bPrivate;
+    }
+
+    public static boolean getLicensed() {
+        return bStackLicensed;
+    }
+}

+ 124 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPVIAHeader.java

@@ -0,0 +1,124 @@
+package bssoft.stack.sip;
+
+import java.util.StringTokenizer;
+
+public class SIPVIAHeader {
+    public String header = null;
+
+    public String headerValue = null;
+
+    public String branch = null;
+
+    public String received = null;
+
+    public int rport = -1;
+
+    public String ip = null;
+
+    public int port = 0;
+
+    public String tag = null;
+
+    public boolean rportService = false;
+
+    public boolean flag = false;
+
+    public SIPVIAHeader(String message) {
+        if (message != null && message.length() > 0) {
+            this.rport = 0;
+            this.received = null;
+            int iS = message.indexOf("Via: ");
+            int iE = 0;
+            if (iS < 0) {
+                iS = message.indexOf(String.valueOf(SIPStack.SIP_LINE_END) + "v: ");
+                if (iS >= 0)
+                    iS += 2;
+            }
+            if (iS >= 0) {
+                iE = message.indexOf(SIPStack.SIP_LINE_END, iS);
+                if (iE > 0) {
+                    this.header = message.substring(iS, iE);
+                    if (this.header.startsWith("Via: ")) {
+                        this.headerValue = this.header.substring(5);
+                    } else if (this.header.startsWith("v: ")) {
+                        this.headerValue = this.header.substring(3);
+                    }
+                }
+            }
+            if (this.headerValue != null && this.headerValue.length() > 0) {
+                StringTokenizer st = new StringTokenizer(this.headerValue, ";", true);
+                int tokenCount = 0;
+                String token = null;
+                while (st.hasMoreTokens()) {
+                    token = st.nextToken().trim();
+                    if (token != null && token.length() > 0 && token.compareTo(";") != 0) {
+                        tokenCount++;
+                        if (tokenCount == 1 && token.startsWith("SIP/")) {
+                            StringTokenizer tokenArray = new StringTokenizer(token, " ", true);
+                            int fieldCount = 0;
+                            while (tokenArray.hasMoreTokens()) {
+                                String field = tokenArray.nextToken().trim();
+                                if (field != null && field.length() > 0 && field.compareTo(" ") != 0) {
+                                    fieldCount++;
+                                    if (fieldCount == 2) {
+                                        iS = field.indexOf(":");
+                                        if (iS > 0) {
+                                            this.port = Integer.parseInt(field.substring(iS + 1));
+                                            this.ip = field.substring(0, iS);
+                                            continue;
+                                        }
+                                        this.port = 5060;
+                                        this.ip = field;
+                                    }
+                                }
+                            }
+                            continue;
+                        }
+                        if (tokenCount != 1 && token.startsWith("branch=")) {
+                            this.branch = token.substring(7);
+                            continue;
+                        }
+                        if (tokenCount != 1 && token.compareTo("rport") == 0) {
+                            this.rportService = true;
+                            continue;
+                        }
+                        if (tokenCount != 1 && token.startsWith("rport=")) {
+                            this.rportService = true;
+                            this.rport = Integer.parseInt(token.substring(6).trim());
+                            continue;
+                        }
+                        if (tokenCount != 1 && token.startsWith("received=")) {
+                            this.rportService = true;
+                            this.received = token.substring(9).trim();
+                        }
+                    }
+                }
+                this.flag = true;
+            }
+        }
+    }
+
+    public String getReceived() {
+        return this.received;
+    }
+
+    public int getRport() {
+        return this.rport;
+    }
+
+    public String getAddress() {
+        return String.valueOf(this.ip) + ":" + this.port;
+    }
+
+    public String getIp() {
+        return this.ip;
+    }
+
+    public int getPort() {
+        return this.port;
+    }
+
+    public String getBranch() {
+        return this.branch;
+    }
+}

+ 38 - 0
WallPadCall/src/main/java/bssoft/stack/sip/SIPmd5.java

@@ -0,0 +1,38 @@
+package bssoft.stack.sip;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SIPmd5 {
+    public MessageDigest md = null;
+
+    public static SIPmd5 md5 = null;
+
+    public SIPmd5() throws NoSuchAlgorithmException {
+        this.md = MessageDigest.getInstance("MD5");
+    }
+
+    public static SIPmd5 getInstance() throws NoSuchAlgorithmException {
+        if (md5 == null)
+            md5 = new SIPmd5();
+        return md5;
+    }
+
+    public String hashData(byte[] dataToHash) {
+        return hexStringFromBytes(calculateHash(dataToHash));
+    }
+
+    public byte[] calculateHash(byte[] dataToHash) {
+        this.md.update(dataToHash, 0, dataToHash.length);
+        return this.md.digest();
+    }
+
+    public String hexStringFromBytes(byte[] b) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < b.length; i++) {
+            String md5Char = String.format("%02x", new Object[] { Integer.valueOf(0xFF & (char)b[i]) });
+            sb.append(md5Char);
+        }
+        return sb.toString();
+    }
+}

+ 294 - 0
WallPadCall/src/main/java/bssoft/stack/sip/UPDATEHeaders.java

@@ -0,0 +1,294 @@
+package bssoft.stack.sip;
+
+import java.util.Date;
+
+public class UPDATEHeaders {
+    public String commandLine = null;
+
+    public String viaH = null;
+
+    public StringBuffer viaArray = null;
+
+    public String routeH = null;
+
+    public StringBuffer routeArray = null;
+
+    public String recordrouteH = null;
+
+    public StringBuffer recordrouteArray = null;
+
+    public String maxforwardH = null;
+
+    public String contactH = null;
+
+    public String toH = null;
+
+    public String fromH = null;
+
+    public String callidH = null;
+
+    public String cseqH = null;
+
+    public String expiresH = null;
+
+    public String allowH = null;
+
+    public String useragentH = null;
+
+    public String remoteuseragentH = null;
+
+    public String contentlengthH = null;
+
+    public String contenttypeH = null;
+
+    public String authorizationINVITEH = null;
+
+    public String authorizationCANCELH = null;
+
+    public String authorizationBYEH = null;
+
+    public String authorizationACKH = null;
+
+    public String passertedidentityH = null;
+
+    public String serverIp = null;
+
+    public int serverPort = 5060;
+
+    public String serverDomain = null;
+
+    public String remoteIp = null;
+
+    public int remotePort = 5060;
+
+    public String remoteContactIp = null;
+
+    public int remoteContactPort = 5060;
+
+    public String remoteContactUri = null;
+
+    public String localIp = null;
+
+    public int localPort = 5060;
+
+    public String id = null;
+
+    public String cid = null;
+
+    public String authid = null;
+
+    public String authpassword = null;
+
+    public String fromTag = null;
+
+    public String toTag = null;
+
+    public String fromHeaderValue = null;
+
+    public String toHeaderValue = null;
+
+    public String callId = null;
+
+    public String dnis = null;
+
+    public String viaBranch = null;
+
+    public int CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+
+    public int INVITE_CSEQ = 0;
+
+    public int CANCEL_CSEQ = 0;
+
+    public int ACK_CSEQ = 0;
+
+    public int BYE_CSEQ = 0;
+
+    public int callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+
+    public int callState = 0;
+
+    public int callMode = SIPStack.SIP_CALLMODE_NONE;
+
+    public Date callTime_TI = null;
+
+    public Date callTime_T0 = null;
+
+    public Date callTime_T00 = null;
+
+    public int invitingTimes = 0;
+
+    public Date callTime_T1 = null;
+
+    public Date callTime_T2 = null;
+
+    public Date callTime_T3 = null;
+
+    public Date callTime_T4 = null;
+
+    public Date callTime_T40 = null;
+
+    public Date callTime_T5 = null;
+
+    public Date callTime_T6 = null;
+
+    public Date callTime_T7 = null;
+
+    public Date callTime_T8 = null;
+
+    public Date callTime_T9 = null;
+
+    public int expiresTI = 0;
+
+    public int expiresT0 = 0;
+
+    public int expiresT00 = 0;
+
+    public int expiresT1 = 0;
+
+    public int expiresT2 = 0;
+
+    public int expiresT3 = 0;
+
+    public int expiresT4 = 0;
+
+    public int expiresT5 = 0;
+
+    public int expiresT6 = 0;
+
+    public int expiresT7 = 0;
+
+    public int expiresT8 = 0;
+
+    public int expiresT9 = 0;
+
+    public SIPSdp sdp = null;
+
+    public SIPSdp remoteSdp = null;
+
+    public String message = null;
+
+    public boolean flag;
+
+    public UPDATEHeaders() {
+        if (SIPStack.SIP_CALLHANDLE_DEBUG)
+            System.out.println("call handle created.");
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_BASIC;
+        this.callTime_TI = new Date();
+        this.callTime_T0 = new Date();
+        this.callTime_T00 = new Date();
+        this.invitingTimes = 0;
+        this.callTime_T1 = new Date();
+        this.callTime_T2 = new Date();
+        this.callTime_T3 = new Date();
+        this.callTime_T4 = new Date();
+        this.callTime_T40 = new Date();
+        this.callTime_T5 = new Date();
+        this.callTime_T6 = new Date();
+        this.callTime_T7 = new Date();
+        this.callTime_T8 = new Date();
+        this.callTime_T9 = new Date();
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.flag = false;
+    }
+
+    public void reset() {
+        this.commandLine = null;
+        this.viaH = null;
+        this.viaArray = null;
+        this.routeH = null;
+        this.routeArray = null;
+        this.recordrouteH = null;
+        this.recordrouteArray = null;
+        this.maxforwardH = null;
+        this.contactH = null;
+        this.toH = null;
+        this.fromH = null;
+        this.callidH = null;
+        this.cseqH = null;
+        this.expiresH = null;
+        this.allowH = null;
+        this.useragentH = null;
+        this.remoteuseragentH = null;
+        this.contentlengthH = null;
+        this.contenttypeH = null;
+        this.authorizationINVITEH = null;
+        this.authorizationCANCELH = null;
+        this.authorizationBYEH = null;
+        this.authorizationACKH = null;
+        this.passertedidentityH = null;
+        this.serverIp = null;
+        this.serverPort = 5060;
+        this.serverDomain = null;
+        this.remoteIp = null;
+        this.remotePort = 5060;
+        this.remoteContactIp = null;
+        this.remoteContactPort = 5060;
+        this.remoteContactUri = null;
+        this.localIp = null;
+        this.localPort = 5060;
+        this.id = null;
+        this.cid = null;
+        this.authid = null;
+        this.authpassword = null;
+        this.fromTag = null;
+        this.toTag = null;
+        this.fromHeaderValue = null;
+        this.toHeaderValue = null;
+        this.callId = null;
+        this.dnis = null;
+        this.viaBranch = null;
+        this.CSEQ_NUMBER = SIPStack.SIP_SEQUENCE_INVITE;
+        this.INVITE_CSEQ = 0;
+        this.CANCEL_CSEQ = 0;
+        this.ACK_CSEQ = 0;
+        this.BYE_CSEQ = 0;
+        this.callDirection = SIPStack.SIP_CALLDIRECTION_NONE;
+        this.callState = 0;
+        this.callMode = SIPStack.SIP_CALLMODE_NONE;
+        this.callTime_TI = null;
+        this.callTime_T0 = null;
+        this.callTime_T00 = null;
+        this.invitingTimes = 0;
+        this.callTime_T1 = null;
+        this.callTime_T2 = null;
+        this.callTime_T3 = null;
+        this.callTime_T4 = null;
+        this.callTime_T40 = null;
+        this.callTime_T5 = null;
+        this.callTime_T6 = null;
+        this.callTime_T7 = null;
+        this.callTime_T8 = null;
+        this.callTime_T9 = null;
+        this.expiresTI = 0;
+        this.expiresT0 = 0;
+        this.expiresT00 = 0;
+        this.expiresT1 = 0;
+        this.expiresT2 = 0;
+        this.expiresT3 = 0;
+        this.expiresT4 = 0;
+        this.expiresT5 = 0;
+        this.expiresT6 = 0;
+        this.expiresT7 = 0;
+        this.expiresT8 = 0;
+        this.expiresT9 = 0;
+        this.sdp = null;
+        this.remoteSdp = null;
+        this.message = null;
+        this.flag = false;
+    }
+}

+ 11 - 0
WallPadCall/src/main/java/bssoft/stack/sip/UserDial.java

@@ -0,0 +1,11 @@
+package bssoft.stack.sip;
+
+public class UserDial {
+    public String dial = "";
+
+    public String dong = "";
+
+    public String ho = "";
+
+    public String latestDial = "";
+}

+ 87 - 0
WallPadCall/src/main/java/bssoft/stack/sip/stackKey.java

@@ -0,0 +1,87 @@
+package bssoft.stack.sip;
+
+public class stackKey {
+    public String KEY_BSS_SMARTINFO;
+
+    public String KEY_BSS_ID;
+
+    public String KEY_BSS_AUTHID;
+
+    public String KEY_BSS_PASSWORD;
+
+    public String KEY_BSS_CID;
+
+    public String KEY_BSS_SERVERIP;
+
+    public String KEY_BSS_SERVERDOMAIN;
+
+    public String KEY_BSS_SERVERPORT;
+
+    public String KEY_BSS_PMPSET;
+
+    public String KEY_BSS_IMSI;
+
+    public String KEY_BSS_GENERALPHONE;
+
+    public String KEY_BSS_WEBID;
+
+    public String KEY_BSS_WEBPWD;
+
+    public String KEY_BSS_LATESTDIAL;
+
+    public String KEY_BSS_FORWARD;
+
+    public String strId = "";
+
+    public String strCid = "";
+
+    public String strAuthid = "";
+
+    public String strAuthpassword = "";
+
+    public String strServerHost = "";
+
+    public String strServerDomain = "";
+
+    public String strImsi = "";
+
+    public String strGeneralPhone = "";
+
+    public String strWebId = "";
+
+    public String strWebPwd = "";
+
+    public int serverPort = 5060;
+
+    public String strForward = "";
+
+    public stackKey() {
+        this.KEY_BSS_SMARTINFO = "bss_smartinfo";
+        this.KEY_BSS_ID = "bss_id";
+        this.KEY_BSS_AUTHID = "bss_authid";
+        this.KEY_BSS_PASSWORD = "bss_password";
+        this.KEY_BSS_CID = "bss_cid";
+        this.KEY_BSS_SERVERIP = "bss_serverip";
+        this.KEY_BSS_SERVERDOMAIN = "bss_serverdomain";
+        this.KEY_BSS_SERVERPORT = "bss_serverport";
+        this.KEY_BSS_PMPSET = "bss_pmpset";
+        this.KEY_BSS_IMSI = "bss_imsi";
+        this.KEY_BSS_GENERALPHONE = "bss_generalphone";
+        this.KEY_BSS_WEBID = "bss_webid";
+        this.KEY_BSS_WEBPWD = "bss_webpwd";
+        this.KEY_BSS_LATESTDIAL = "bss_latestdial";
+        this.KEY_BSS_FORWARD = "bss_forward";
+        this.strId = "";
+        this.strCid = "";
+        this.strAuthid = "";
+        this.strAuthpassword = "";
+        this.strServerHost = "";
+        this.strServerDomain = "";
+        this.strImsi = "";
+        this.strGeneralPhone = "";
+        this.strWebId = "";
+        this.strWebPwd = "";
+        this.serverPort = 5060;
+        this.strForward = "";
+    }
+}

+ 228 - 0
WallPadCall/src/main/java/bssoft/stack/sip/videoEnc.java

@@ -0,0 +1,228 @@
+package bssoft.stack.sip;
+
+public class videoEnc {
+    public boolean bReceiveRunning = false;
+
+    public byte[] buffer = null;
+
+    public byte[] rtpVideoBuffer = null;
+
+    public byte[] data = null;
+
+    public int RTP_VIDEO_SIZE = 50000;
+
+    public int RTPversion = 0;
+
+    public int RTPpadding = 0;
+
+    public int RTPextension = 0;
+
+    public int RTPcsrc = 0;
+
+    public int RTPmark = 0;
+
+    public int RTPpayload = 0;
+
+    public int RTPsequence = 0;
+
+    public int RTPtimestamp = 0;
+
+    public int RTPssrc = 0;
+
+    public boolean bService = false;
+
+    public String remoteIp = "127.0.0.1";
+
+    public int remotePort = 3002;
+
+    public byte[] rtpfieldBytes = null;
+
+    public boolean bIframeset = false;
+
+    public boolean bIframedoubleset = false;
+
+    public boolean bView = false;
+
+    public int PARSEversion = 0;
+
+    public int PARSEpadding = 0;
+
+    public int PARSEextension = 0;
+
+    public int PARSEcsrc = 0;
+
+    public int PARSEmark = 0;
+
+    public int PARSEpayload = 0;
+
+    public int PARSEsequence = 0;
+
+    public int PARSEtimestamp = 0;
+
+    public int PARSEssrc = 0;
+
+    public int PARSEview = 0;
+
+    public videoEnc() {
+        if (!SIPStack.bStackLicensed) {
+            System.out.println("라이슨스키를 설정하세요.");
+                    System.exit(0);
+        }
+        this.buffer = new byte[this.RTP_VIDEO_SIZE];
+        this.rtpVideoBuffer = new byte[this.RTP_VIDEO_SIZE];
+        this.data = new byte[this.RTP_VIDEO_SIZE];
+        this.RTPversion = 0;
+        this.RTPpadding = 0;
+        this.RTPextension = 0;
+        this.RTPcsrc = 0;
+        this.RTPmark = 0;
+        this.RTPpayload = 0;
+        this.RTPsequence = 0;
+        this.RTPtimestamp = 0;
+        this.RTPssrc = 0;
+        this.bService = false;
+        this.remoteIp = "127.0.0.1";
+        this.remotePort = 3002;
+        this.rtpfieldBytes = new byte[4];
+        this.bIframeset = false;
+        this.bIframedoubleset = false;
+        this.bView = false;
+    }
+
+    public void init() {
+        this.RTPversion = 0;
+        this.RTPpadding = 0;
+        this.RTPextension = 0;
+        this.RTPcsrc = 0;
+        this.RTPmark = 0;
+        this.RTPpayload = 0;
+        this.RTPsequence = 0;
+        this.RTPtimestamp = 0;
+        this.RTPssrc = 0;
+        this.bService = false;
+        this.remoteIp = "127.0.0.1";
+        this.remotePort = 3002;
+        this.bIframeset = false;
+        this.bIframedoubleset = false;
+        this.bView = false;
+    }
+
+    public boolean encodeRtpHeader(int payload) {
+        if (this.rtpVideoBuffer == null || this.rtpVideoBuffer.length < 12)
+            return false;
+        int iField = 0;
+        int iAppend = 0;
+        iField = this.RTPversion << 6 & 0xC0;
+        iAppend = this.RTPpadding << 5 & 0x20;
+        iField |= iAppend;
+        iAppend = this.RTPextension << 4 & 0x10;
+        iField |= iAppend;
+        iAppend = this.RTPcsrc & 0xF;
+        iField |= iAppend;
+        this.rtpVideoBuffer[0] = (byte)iField;
+        iField = 0;
+        iField = this.RTPmark << 7 & 0x80;
+        iAppend = payload & 0x7F;
+        iField |= iAppend;
+        this.rtpVideoBuffer[1] = (byte)iField;
+        iField = 0;
+        this.rtpVideoBuffer[2] = (byte)(this.RTPsequence << 16 >> 24);
+        this.rtpVideoBuffer[3] = (byte)(this.RTPsequence << 24 >> 24);
+        this.rtpVideoBuffer[4] = (byte)(this.RTPtimestamp >> 24);
+        this.rtpVideoBuffer[5] = (byte)(this.RTPtimestamp << 8 >> 24);
+        this.rtpVideoBuffer[6] = (byte)(this.RTPtimestamp << 16 >> 24);
+        this.rtpVideoBuffer[7] = (byte)(this.RTPtimestamp << 24 >> 24);
+        this.rtpVideoBuffer[8] = (byte)(this.RTPssrc >> 24);
+        this.rtpVideoBuffer[9] = (byte)(this.RTPssrc << 8 >> 24);
+        this.rtpVideoBuffer[10] = (byte)(this.RTPssrc << 16 >> 24);
+        this.rtpVideoBuffer[11] = (byte)(this.RTPssrc << 24 >> 24);
+        return true;
+    }
+
+    public boolean encodeHNSRtpHeader(int payload, boolean bView) {
+        if (this.rtpVideoBuffer == null || this.rtpVideoBuffer.length < 12)
+            return false;
+        int iField = 0;
+        int iAppend = 0;
+        iField = this.RTPversion << 6 & 0xC0;
+        iAppend = this.RTPpadding << 5 & 0x20;
+        iField |= iAppend;
+        iAppend = this.RTPextension << 4 & 0x10;
+        iField |= iAppend;
+        iAppend = this.RTPcsrc & 0xF;
+        iField |= iAppend;
+        this.rtpVideoBuffer[0] = (byte)iField;
+        iField = 0;
+        iField = this.RTPmark << 7 & 0x80;
+        iAppend = payload & 0x7F;
+        iField |= iAppend;
+        this.rtpVideoBuffer[1] = (byte)iField;
+        iField = 0;
+        this.rtpVideoBuffer[2] = (byte)(this.RTPsequence << 16 >> 24);
+        this.rtpVideoBuffer[3] = (byte)(this.RTPsequence << 24 >> 24);
+        this.rtpVideoBuffer[4] = (byte)(this.RTPtimestamp >> 24);
+        this.rtpVideoBuffer[5] = (byte)(this.RTPtimestamp << 8 >> 24);
+        this.rtpVideoBuffer[6] = (byte)(this.RTPtimestamp << 16 >> 24);
+        this.rtpVideoBuffer[7] = (byte)(this.RTPtimestamp << 24 >> 24);
+        this.rtpVideoBuffer[8] = (byte)(this.RTPssrc >> 24);
+        this.rtpVideoBuffer[9] = (byte)(this.RTPssrc << 8 >> 24);
+        this.rtpVideoBuffer[10] = (byte)(this.RTPssrc << 16 >> 24);
+        this.rtpVideoBuffer[11] = (byte)(this.RTPssrc << 24 >> 24);
+        if (bView) {
+            iField = 1;
+        } else {
+            iField = 0;
+        }
+        this.rtpVideoBuffer[12] = (byte)iField;
+        return true;
+    }
+
+    public boolean parseRTPHeader() {
+        try {
+            this.PARSEversion = 0;
+            this.PARSEpadding = 0;
+            this.PARSEextension = 0;
+            this.PARSEcsrc = 0;
+            this.PARSEmark = 0;
+            this.PARSEpayload = 0;
+            this.PARSEsequence = 0;
+            this.PARSEtimestamp = 0;
+            this.PARSEssrc = 0;
+            this.PARSEview = 0;
+            this.rtpfieldBytes[0] = this.buffer[1];
+            this.PARSEmark = this.rtpfieldBytes[0] >> 7 & 0x1;
+            this.PARSEpayload = this.rtpfieldBytes[0] & Byte.MAX_VALUE;
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean parseHNSRTPHeader() {
+        try {
+            this.PARSEversion = 0;
+            this.PARSEpadding = 0;
+            this.PARSEextension = 0;
+            this.PARSEcsrc = 0;
+            this.PARSEmark = 0;
+            this.PARSEpayload = 0;
+            this.PARSEsequence = 0;
+            this.PARSEtimestamp = 0;
+            this.PARSEssrc = 0;
+            this.PARSEview = 0;
+            this.rtpfieldBytes[0] = this.buffer[1];
+            this.PARSEmark = this.rtpfieldBytes[0] >> 7 & 0x1;
+            this.PARSEpayload = this.rtpfieldBytes[0] & Byte.MAX_VALUE;
+            this.rtpfieldBytes[0] = this.buffer[12];
+            this.PARSEview = this.rtpfieldBytes[0] & 0x1;
+            if (this.PARSEview == 1) {
+                this.bView = true;
+            } else {
+                this.bView = false;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+}

+ 47 - 5
WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/CallController.java

@@ -363,6 +363,7 @@ public class CallController extends CallManager implements SIPEventListener {
             if (IP_Parse[2].equals("128")) strTailID = IP_Parse[3];   // 경비실
             else if (IP_Parse[2].equals("0")) strTailID = IP_Parse[3];   // 로비폰
             else if (IP_Parse[2].equals("201")) strTailID = IP_Parse[3];   // 아이허브
+            else if (IP_Parse[2].equals("129")) strTailID = IP_Parse[3];   // 아이허브
             else {
                 if (ConfigValues.bEnableHouseDivision) {
                     int nTailID = Integer.parseInt(IP_Parse[3]);
@@ -386,11 +387,16 @@ public class CallController extends CallManager implements SIPEventListener {
                 ((MainActivity) mContext).changeMenuNScreen(ID.MENU.MENU_TALKGUARD);
                 return CALLTYPE.GUARD;
             } else if (IP_Parse[2].equals("0")) {
+                if(IP_Parse[3].equals("11"))
+                    return CALLTYPE.FRONT;
                 // Lobby
                 return CALLTYPE.LOBBY;
             } else if (IP_Parse[2].equals("201")) {
                 // Ihub
                 return CALLTYPE.IHUB;
+            } else if (IP_Parse[2].equals("129")) {
+                // Ihub
+                return CALLTYPE.FRONT;
             } else {
                 int nType = Integer.parseInt(IP_Parse[2]);
                 if (0 < nType && nType < 100) {
@@ -658,10 +664,10 @@ public class CallController extends CallManager implements SIPEventListener {
                         if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT) {
 //                            ((MainActivity) mContext).sendHandlerMsg(MainActivity.HANDLERMSG.SET_DINGDONG_VOLUME, 0, 0); // 현관띵똥 볼륨 고정(시스템 볼륨 따라가지 않도록)
 //                            sendHandlerMsg(HANDLERMSG.SETTALKPATH_DOORMUSIC, 0, 0);
-                            if (TalkFront.BTN_TALK != null) { // 현관 단일콜일 경우 띵똥 소리 출력 중인 경우에는 통화버튼 disable
-                                if (ConfigValues.bReliefCall) TalkFront.BTN_TALK.setButtonEventOffEnable(R.drawable.btn_call_disabled);
-                                else TalkFront.BTN_TALK.setButtonEventOffEnable(R.drawable.btn_front_call_disabled);
-                            }
+//                            if (TalkFront.BTN_TALK != null) { // 현관 단일콜일 경우 띵똥 소리 출력 중인 경우에는 통화버튼 disable
+//                                if (ConfigValues.bReliefCall) TalkFront.BTN_TALK.setButtonEventOffEnable(R.drawable.btn_call_disabled);
+//                                else TalkFront.BTN_TALK.setButtonEventOffEnable(R.drawable.btn_front_call_disabled);
+//                            }
                         }
 //                        ((MainActivity) mContext).mCallPathCheckHandler.sendEmptyMessage(0); // 대외향 월패드 현관카메라 띵똥을 WallPadMain으로 코드 이동
                         ((MainActivity) mContext).changeMenuNScreen(ID.MENU.MENU_TALKFRONT);
@@ -1072,8 +1078,44 @@ public class CallController extends CallManager implements SIPEventListener {
     @Override
     public void onSIPEvent(CALLEVENTTYPE eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
         try {
-            LOG("[onSIPEvent] eEventType [" + eEventType + "], eCallType [" + eCallType + "]");
+            LOG("[onSIPEvent] eEventType [" + eEventType + "], eCallType [" + eCallType + "]"+ "], strRemoteIP [" + strRemoteIP + "]"+ "], strRemoteSIPID [" + strRemoteSIPID + "]");
+
+            if(eEventType == CALLEVENTTYPE.TERMINATE_CALL)
+            {
+                if(strRemoteIP == null)
+                    strRemoteIP = RemoteIDInfo.strIP;
+            }
+
+            if(strRemoteIP != null)
+            {
+                strRemoteSIPID = makeSIPID(strRemoteIP);
+
+                //if(eEventType != CALLEVENTTYPE.RECEIVE_CALL)
+                {
+                    if (strRemoteSIPID.contains("_Guard_")) {
+                        eCallType = CALLTYPE.GUARD;
+                    } else if (strRemoteSIPID.contains("_Lobby_")) {
+
+                        eCallType = CALLTYPE.LOBBY;
+                    } else if (strRemoteSIPID.contains("_Resi_")) {
+
+                        eCallType = CALLTYPE.RESIDENCE;
+                    } else if (strRemoteSIPID.contains("_Front_")) {
+
+                        eCallType = CALLTYPE.FRONT;
+                    }else {
+
+                        eCallType = CALLTYPE.NONE;
+                    }
+                }
+            }
+
             CallScenarioManager(mCallInfo.getCallOwner(), eEventType, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
+
+            if((eCallType == CALLTYPE.LOBBY) || (eCallType == CALLTYPE.FRONT))
+                acceptMoIPCall(false);
+
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {

+ 24 - 2
WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/CallManager.java

@@ -1069,10 +1069,18 @@ public class CallManager {
                 // 로비폰
                 strType = DEVICENAME.strType_Lobby;
                 ho = IP_Parse[3];
+
+                if(IP_Parse[3].equals("11"))
+                    strType = DEVICENAME.strType_Front;
+
             } else if (IP_Parse[2].equals("201")) {
                 // 아이허브
                 strType = DEVICENAME.strType_Ihub;
                 ho = IP_Parse[3];
+            } else if (IP_Parse[2].equals("129")) {
+                // Ihub
+                strType = DEVICENAME.strType_Front;
+                ho = IP_Parse[3];
             } else {
                 strType = Declare.DEVICENAME.strType_Resi;
                 ho = IP_Parse[2] + Global.ZeroPadding_Head(2, IP_Parse[3]);
@@ -1123,8 +1131,15 @@ public class CallManager {
             String[] IP_Parse = strIPAddress.split("\\.");
 
             if (IP_Parse[2].equals("128")) return CALLTYPE.GUARD;
-            else if (IP_Parse[2].equals("0")) return CALLTYPE.LOBBY;
+            else if (IP_Parse[2].equals("0"))
+            {
+                if(IP_Parse[3].equals("11"))
+                    return CALLTYPE.FRONT;
+
+                return CALLTYPE.LOBBY;
+            }
             else if (IP_Parse[2].equals("201")) return CALLTYPE.IHUB;
+            else if (IP_Parse[2].equals("129")) return CALLTYPE.FRONT;
             else return CALLTYPE.RESIDENCE;
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -1144,8 +1159,14 @@ public class CallManager {
             String[] IP_Parse = strIPAddress.split("\\.");
 
             if (IP_Parse[2].equals("128")) return CALLTYPE.GUARD;
-            else if (IP_Parse[2].equals("0")) return CALLTYPE.LOBBY;
+            else if (IP_Parse[2].equals("0"))
+            {
+                if(IP_Parse[3].equals("11"))
+                    return CALLTYPE.FRONT;
+                return CALLTYPE.LOBBY;
+            }
             else if (IP_Parse[2].equals("201")) return CALLTYPE.IHUB;
+            else if (IP_Parse[2].equals("129")) return CALLTYPE.FRONT;
             else return CALLTYPE.RESIDENCE;
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -1163,6 +1184,7 @@ public class CallManager {
     CALLTYPE eCallTypeTimer;
 
     public class CTT {   // CTT = Call Timeout Table, 단위 Sec
+        public int TIMEOUT_SEC_1 = 1;
         public int TIMEOUT_SEC_10 = 10;
         public int TIMEOUT_SEC_30 = 30;
         public int TIMEOUT_SEC_60 = 60;

+ 8 - 8
WallPadCall/src/main/java/kr/co/icontrols/callengine/engine/SIPInterface.java

@@ -1951,7 +1951,7 @@ public class SIPInterface {
             try {
                 LOG_INFO("[VideoRtpmanager] VideoRtpmanager started!");
                 try {
-                    RTP_PORT = SIPController.sipCall.sdp.audioM.mediaPort + 2;
+                    RTP_PORT = 3002;
                     LOG_INFO("[VideoRtpmanager] Video Port [" + RTP_PORT + "]");
 
                     theSocket = new DatagramSocket(RTP_PORT);
@@ -1969,19 +1969,19 @@ public class SIPInterface {
                     return;
                 }
 
-                LOG_INFO("[VideoRtpmanager] ------- videoenc.init() -------");
+                //LOG_INFO("[VideoRtpmanager] ------- videoenc.init() -------");
                 videoenc.init();
                 videoenc.bReceiveRunning = true;
                 runningSocket = theSocket;
                 videoenc.bService = true;
                 bOpenCover = false;
 
-                Log.e(TAG, "[VideoRtpmanager] videoenc.bReceiveRunning [" + videoenc.bReceiveRunning + "]");
+                //Log.e(TAG, "[VideoRtpmanager] videoenc.bReceiveRunning [" + videoenc.bReceiveRunning + "]");
                 if (runningSocket == null ) Log.e(TAG, "[VideoRtpmanager] runningSocket is null!!");
                 else Log.d(TAG, "[VideoRtpmanager] runningSocket is not null!!");
 
                 while (videoenc.bReceiveRunning == true && runningSocket != null) {
-//                    Log.e(TAG, "[VideoRtpmanager] ===== while =====");
+                    //Log.e(TAG, "[VideoRtpmanager] ===== while =====");
                     try {
                         if (videoManager == null) {
                             Log.e(TAG, "[VideoRtpmanager] videoManager == null");
@@ -2009,7 +2009,7 @@ public class SIPInterface {
 
                         if (SIPController.dp == null) Log.e(TAG, "[VideoRtpmanager] SIPController.dp is null!!!");
 
-//                        Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [1] =================");
+                        //Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [1] =================");
                         if (SIPController.dp != null && SIPController.dp.getLength() > 0) {
 //                            Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [2] =================");
                             if (false == videoenc.parseHNSRTPHeader()) {
@@ -2047,7 +2047,7 @@ public class SIPInterface {
                                 continue;
                             }
 
-//                            Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [6] =================");
+                            //Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [6] =================");
                             if (bOpenCover == false) {
 //                                Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [7] =================");
                                 if (videoenc.bIframeset == false) {
@@ -2074,7 +2074,7 @@ public class SIPInterface {
                                 }
                             }
 
-//                            Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [8] =================");
+                            //Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [8] =================");
                             byte[] field = new byte[4];
                             System.arraycopy(videoenc.buffer, 13, field, 0, 4);
                             int headerLen = getIntByByteArr(field);
@@ -2084,7 +2084,7 @@ public class SIPInterface {
                             int timeStamp = getIntByByteArr(field);
                             int frameSize = (frameLen > 0) ? frameLen : headerLen;
 
-//                            Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [9] =================");
+                            //Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [9] =================");
                             if (SIPController.dp.getLength() - 25 >= frameSize && bDecoderStarted == true) {
 //                                Log.e(TAG, "[VideoRtpmanager] ================= VIDEO RTP [10] =================");
                                 System.arraycopy(videoenc.buffer, 25, videoenc.data, 0, frameSize);

+ 8 - 1
WallPadCall/src/main/java/kr/co/icontrols/callengine/sip/SIPSound.java

@@ -563,8 +563,15 @@ public class SIPSound {
             Log.i(TAG, "[getCallType] strIPAddress [" + strIPAddress + "]");
             String[] IP_Parse = strIPAddress.split("\\.");
             if (IP_Parse[2].equals("128")) return CALLTYPE.GUARD;
-            else if (IP_Parse[2].equals("0")) return CALLTYPE.LOBBY;
+            else if (IP_Parse[2].equals("0"))
+            {
+                if(IP_Parse[3].equals("11"))
+                    return CALLTYPE.FRONT;
+
+                return CALLTYPE.LOBBY;
+            }
             else if (IP_Parse[2].equals("201")) return CALLTYPE.IHUB;
+            else if (IP_Parse[2].equals("129")) return CALLTYPE.FRONT;
             else return CALLTYPE.RESIDENCE;
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);

+ 23 - 9
WallPadCall/src/main/java/kr/co/icontrols/callengine/sip/SIPStun.java

@@ -2199,10 +2199,10 @@ public class SIPStun extends Service {
     public void INVITEParser(String strMessage, int nMSGType, String strRemoteIP, int strRemotePort) {
         try {
             Log.w(TAG, "[INVITEParser] bBLOCK_INVITE_MSG [" + bBLOCK_INVITE_MSG + "]");
-            if (bBLOCK_INVITE_MSG) {
-                rejectCall(strMessage, 486, strRemoteIP, strRemotePort);
-                return;
-            }
+//            if (bBLOCK_INVITE_MSG) {
+//                rejectCall(strMessage, 486, strRemoteIP, strRemotePort);
+//                return;
+//            }
 
             if (nMSGType == SIPStack.SIP_MSGTYPE_REQUEST) {
                 if (SIPController.sipCall != null) {
@@ -2271,7 +2271,9 @@ public class SIPStun extends Service {
                                                     fromId = sipHeader.getId().trim();
                                                 }
                                             }
-
+                                            Log.d(TAG, "[INVITEParser1] cmcore.id [" + cmcore.id + "], toId [" + toId + "]");
+                                            //toId = "12345678_Resi_0101_0103_01";
+                                            //fromId
                                             Log.d(TAG, "[INVITEParser] cmcore.id [" + cmcore.id + "], toId [" + toId + "]");
                                             if (cmcore.id != null && toId.compareTo(cmcore.id) == 0) {
                                                 // activate call handler
@@ -2351,7 +2353,8 @@ public class SIPStun extends Service {
                                 }
                             }
 
-                            Log.d(TAG, "[INVITEParser] cmcore.id [" + cmcore.id + "], toId [" + toId + "]");
+                            Log.d(TAG, "[INVITEParser3] cmcore.id [" + cmcore.id + "], toId [" + toId + "]");
+                            //toId = "12345678_Resi_0101_0103_01";
 
                             if (cmcore.id != null && toId.compareTo(cmcore.id) == 0) {
                                 // activate call handler
@@ -2366,7 +2369,8 @@ public class SIPStun extends Service {
                                 else {
                                     Log.i(TAG, "[INVITEParser] New call. Dialer awaken.");
                                     Log.i(TAG, "[INVITEParser] strRemoteIP [" + strRemoteIP + "], fromId [" + fromId + "]");
-                                    receiveNewCall(strRemoteIP, fromId);
+
+                                    receiveNewCall(strRemoteIP, makeSIPID(fromId));
                                     Log.d(TAG, "[INVITEParser] CMCore.bDialerActive [" + CMCore.bDialerActive + "]");
 
                                     // CMCore.bDialerActive는 GUI의 foreground 여부를 의미한다. (true: foreground)
@@ -4652,7 +4656,7 @@ public class SIPStun extends Service {
         RECEIVE,   // 수신
     }
 
-    boolean bPrintSIPMsg = false;
+    boolean bPrintSIPMsg = true;
     boolean bPrintSIPMsgIO = false;
 
     private void printSIPMessage(MESSAGE eType, String strMessage) {
@@ -4675,6 +4679,7 @@ public class SIPStun extends Service {
         public static String strType_Lobby = "Lobby";
         public static String strType_Guard = "Guard";
         public static String strType_Ihub = "Ihub";
+        public static String strType_Front = "Front";
     }
 
     public String[] makeDeviceName(String ipaddress) {
@@ -4745,10 +4750,18 @@ public class SIPStun extends Service {
                     // 로비폰
                     strType = DeviceString.strType_Lobby;
                     ho = IP_Parse[3];
+
+                    if(IP_Parse[3].equals("11"))
+                        strType = Declare.DEVICENAME.strType_Front;
                 } else if (IP_Parse[2].equals("201")) {
                     // 아이허브
                     strType = DeviceString.strType_Ihub;
                     ho = IP_Parse[3];
+                }
+                else if (IP_Parse[2].equals("129")) {
+                    // 아이허브
+                    strType = DeviceString.strType_Front;
+                    ho = IP_Parse[3];
                 } else {
                     int nIP_DClass = Integer.parseInt(IP_Parse[3]);
 
@@ -4886,7 +4899,8 @@ public class SIPStun extends Service {
                 return;
             }
 
-            runCallMainActivity(mCALLEVENTTYPE, mCALLTYPE);
+            if(mCALLTYPE == CALLTYPE.RESIDENCE)
+                runCallMainActivity(mCALLEVENTTYPE, mCALLTYPE);
 
             sendHandlerMsgDelayed(HANDLERMSG.RELEASE_BLOCK_INVITE_MSG, 0, 0, 0);
 

+ 1 - 2
WallPadCall/src/main/java/kr/co/icontrols/callengine/subphone/SubPhoneSerialManager.java

@@ -1369,8 +1369,7 @@ public class SubPhoneSerialManager extends Service {
             byte hDATA1 = 0x00, hDATA2 = 0x00, hDATA3 = 0x00, hDATA4 = 0x00;
             if (eCallType == CALLTYPE.FRONT) {
                 hDATA1 = SubPhoneCmds.CALLTYPE_FRONT;
-//                Log.e(TAG, "[sendNotifyNewCall] Build.VERSION.SDK_INT: " + Build.VERSION.SDK_INT);
-                if ((getSmartIoTCameraUsage() && ConfigValues.bSmartIOTCamFlip) || !(Build.VERSION.SDK_INT > 23)) hDATA4 = (byte) 0x01;
+                if (getSmartIoTCameraUsage() && ConfigValues.bSmartIOTCamFlip) hDATA4 = (byte) 0x01;
             }
             else if (eCallType == CALLTYPE.LOBBY) hDATA1 = SubPhoneCmds.CALLTYPE_LOBBY;
             else if (eCallType == CALLTYPE.GUARD) {

+ 115 - 14
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/MainActivity.java

@@ -53,6 +53,7 @@ import com.artncore.wallpadapi.IGW300API;
 import com.artncore.wallpadapi.Sdb_LivingRoomLightAPI;
 import com.artncore.wallpadapi.SmartKeyRfDoorAPI;
 import com.artncore.wallpadapi.WallPadAPI;
+import com.artncore.wallpadimap.RetProci;
 import com.util.LogUtil;
 
 import java.io.BufferedInputStream;
@@ -105,6 +106,7 @@ import kr.co.icontrols.wallpadcall.declare.Global.FRONTCAMERATYPE;
 import kr.co.icontrols.wallpadcall.declare.Global.SUBWALLPAD_PSTNTYPE;
 import kr.co.icontrols.wallpadcall.declare.Global.WALLPADTYPE;
 import kr.co.icontrols.wallpadcall.declare.ID;
+import kr.co.icontrols.wallpadcall.imap.Request_check_sip_activation;
 import kr.co.icontrols.wallpadcall.screen.InquiryCallHistory;
 import kr.co.icontrols.wallpadcall.screen.InquiryVisitorPictureHistory;
 import kr.co.icontrols.wallpadcall.screen.TalkFront;
@@ -238,6 +240,8 @@ public class MainActivity extends WpadActivity {
     private Menu mMenu = null; // WPadAPI의 Menu class
     private boolean MenuOpen = false;
 
+    public boolean mNewDanjiServer = false;
+
     // PopupActivityRun
     private static boolean PopupActivityRun = false;
 
@@ -625,6 +629,11 @@ public class MainActivity extends WpadActivity {
             getResidentSafetyCheckSetting();
 
             // 8. Window Resize
+
+            WallpadDeviceSet wallpadDeviceSet = new WallpadDeviceSet(getApplicationContext());
+            mNewDanjiServer =  wallpadDeviceSet.GetNewDanjiServer();
+            wallpadDeviceSet.closeDB();
+
             LOG_INFO("[Create] - Step8 : Window Resize");
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -1345,7 +1354,7 @@ public class MainActivity extends WpadActivity {
             switch (nScreenId) {
                 case API_Menu.SubMenuCall.Door:
                     setTitleText(API_Menu.SubMenuCall.Name_Door);
-                    ScreenTalkFront = new TalkFront(this, ScreenLayout, mWallPadAPI);
+                    ScreenTalkFront = new TalkFront(this, ScreenLayout);
                     super.setCurrentScreen(ScreenTalkFront);
                     break;
 
@@ -2297,6 +2306,42 @@ public class MainActivity extends WpadActivity {
         }
     }
 
+    private boolean send_check_sip_activation_request(final String strTargetIP) {
+        try {
+            Request_check_sip_activation check_sip_activation = new Request_check_sip_activation(mContext);
+            if (check_sip_activation.send_check_sip_activation(strTargetIP, null)) {
+                check_sip_activation.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        LOG_INFO("[send_check_sip_activation_request] ProcSuccess()");
+                       // MainActivity.mCallController.mSIPInterface.requestCallForwardToStun(MainActivity.mCallController.makeCallForwarInfo(strTargetIP));
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_check_sip_activation_request] ProcError()");
+                       // MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_check_sip_activation_request] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_check_sip_activation_request(String strTargetIP, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+        }
+        return false;
+    }
+
     String strCallOwner = "NONE";
     String strCallEvent = "NONE";
     String strCallType = "NONE";
@@ -2305,6 +2350,7 @@ public class MainActivity extends WpadActivity {
     private void generateCallEvent() {
         try {
             LOG_INFO("[generateCallEvent] ConfigValues.eWallPadType [" + ConfigValues.eWallPadType + "], strCallOwner [" + strCallOwner + "], strCallEvent [" + strCallEvent + "], strCallType [" + strCallType + "], strRemoteInfo [" + strRemoteInfo + "]");
+
             if (strCallEvent.equalsIgnoreCase("NONE")) setMenuBTNEnable(true);
             else setMenuBTNEnable(false);
 
@@ -2319,7 +2365,9 @@ public class MainActivity extends WpadActivity {
                     if (callowner == CALLOWNER.NONE) {
                         if (calltype == CALLTYPE.FRONT) {
                             if (calleventtype == CALLEVENTTYPE.RECEIVE_CALL) {
-                                if (mCallController != null) mCallController.CallScenarioManager(callowner, calleventtype, calltype, null, null, null);
+                                String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+                                if (mCallController != null) mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, strRemoteSIPID, null);
+                                //if (mCallController != null) mCallController.CallScenarioManager(callowner, calleventtype, calltype, null, null, null);
                                 else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
                             }
                             else {
@@ -2345,7 +2393,17 @@ public class MainActivity extends WpadActivity {
                             }
                         }
                         else {
+                            if (calleventtype == CALLEVENTTYPE.RECEIVE_CALL) {
+                                String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+                                if (mCallController != null) mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, strRemoteSIPID, null);
+                                else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
+                            }
+                            else {
+                                Log.w(TAG, "[generateCallEvent] not supported callevent!! -> " + calleventtype);
+                            }
+
                             Log.w(TAG, "[generateCallEvent] not supported calltype!! -> " + calltype);
+                            RemoteIDInfo.strIP = strRemoteInfo;
                         }
                     }
                     else if (callowner == CALLOWNER.WALLPAD) {
@@ -2353,7 +2411,16 @@ public class MainActivity extends WpadActivity {
                             if (calleventtype == CALLEVENTTYPE.REQUEST_FRONT_MONITORING) {
                                 if (mCallController != null) {
                                     mCallController.mCallInfo.setCallOwner(callowner);
-                                    mCallController.CallScenarioManager(callowner, calleventtype, calltype, null, null, null);
+
+                                    strRemoteInfo = "10.1.0.11";
+                                    String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+                                    RemoteIDInfo.strIP = strRemoteInfo;
+
+                                    if (send_check_sip_activation_request(strRemoteInfo))
+                                        mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, strRemoteSIPID, null);
+                                    else
+                                        Log.d(TAG, callowner.toString() + "REQUEST_FRONT_MONITORING check_sip_activation ERROR");
+                                    //mCallController.CallScenarioManager(callowner, calleventtype, calltype, null, null, null);
                                 }
                                 else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
                             }
@@ -2367,6 +2434,13 @@ public class MainActivity extends WpadActivity {
                             }
                             else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
                         }
+
+//                        else if (calltype == CALLTYPE.LOBBY) {
+//                            if (mCallController != null) {
+//                                mCallController.mCallInfo.setCallOwner(callowner);
+//                                mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, null, null);
+//                            }
+//                        }
                     }
                     else if (callowner == CALLOWNER.MOBILE) {
                         if (calltype == CALLTYPE.FRONT) {
@@ -2374,7 +2448,14 @@ public class MainActivity extends WpadActivity {
                             if (calleventtype == CALLEVENTTYPE.REQUEST_FRONT_MONITORING) {
                                 if (mCallController != null) {
                                     mCallController.mCallInfo.setCallOwner(callowner);
-                                    mCallController.CallScenarioManager(callowner, calleventtype, calltype, null, null, null);
+                                    strRemoteInfo = "10.1.0.11";
+                                    String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+                                    RemoteIDInfo.strIP = strRemoteInfo;
+
+                                    if (send_check_sip_activation_request(strRemoteInfo))
+                                        mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, strRemoteSIPID, null);
+                                    else
+                                        Log.d(TAG, callowner.toString() + "REQUEST_FRONT_MONITORING check_sip_activation ERROR");
                                 }
                                 else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
                             }
@@ -2402,7 +2483,17 @@ public class MainActivity extends WpadActivity {
                     }
                     else if (Global.getKitchenTVIdx(callowner) >= 0 || Global.getBathPhoneIdx(callowner) >= 0 || callowner == CALLOWNER.SUB_WALLPAD || Global.getBathTVIdx(callowner) >= 0) {
                         if (calltype == CALLTYPE.FRONT) {
-                            if (mCallController != null) mCallController.onSubPhoneEvent(callowner, calleventtype, calltype, null, null);
+                            if (mCallController != null)
+                            {
+                                strRemoteInfo = "10.1.0.11";
+                                String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+                                RemoteIDInfo.strIP = strRemoteInfo;
+                                //mCallController.onSubPhoneEvent(callowner, calleventtype, calltype, null, null);
+                                if (send_check_sip_activation_request(strRemoteInfo))
+                                    mCallController.onSubPhoneEvent(callowner, calleventtype, calltype, strRemoteSIPID, null);
+                                else
+                                    Log.d(TAG, callowner.toString() + "REQUEST_FRONT_MONITORING check_sip_activation ERROR");
+                            }
                             else Log.w(TAG, "[generateCallEvent] mCallController is null!!");
                         }
                         else if (calltype == CALLTYPE.GUARD || calleventtype == CALLEVENTTYPE.TRYING_CALL) {
@@ -2431,8 +2522,20 @@ public class MainActivity extends WpadActivity {
                             }
                             else Log.w(TAG, "[generateCallEvent] not supported calleventtype!! -> " + calleventtype);
                         }
+//                        else if(calltype == CALLTYPE.HISTORY_CALL)
+//                        {
+//                            strRemoteInfo = "10.1.0.110";
+//                            String strRemoteSIPID = mCallController.makeSIPID(strRemoteInfo);
+//                            RemoteIDInfo.strIP = strRemoteInfo;
+//
+//                            if (send_check_sip_activation_request(strRemoteInfo))
+//                                if (mCallController != null) mCallController.CallScenarioManager(callowner, calleventtype, calltype, strRemoteInfo, strRemoteSIPID, null);
+//                            else
+//                                Log.d(TAG, callowner.toString() + "REQUEST_FRONT_MONITORING check_sip_activation ERROR");
+//                        }
                         else {
                             Log.w(TAG, "[generateCallEvent] not supported calltype!! -> " + callowner);
+                            RemoteIDInfo.strIP = strRemoteInfo;
                         }
                     }
                     else if (callowner == CALLOWNER.SUB_WALLPAD) {
@@ -2441,6 +2544,8 @@ public class MainActivity extends WpadActivity {
                                 mCallController.mCallInfo.setCallOwner(callowner);
                                 mCallController.onSubWallPadEvent(callowner, calleventtype, calltype, null, null);
                                 mSubWallPadController.sendRequestFrontMonitoring(CALLOWNER.SUB_WALLPAD, CALLTYPE.FRONT);
+
+
                             }
                             else {
                                 Log.w(TAG, "[generateCallEvent] mCallController is null!!");
@@ -3815,7 +3920,7 @@ public class MainActivity extends WpadActivity {
     public Bitmap flipTakenIMG(Bitmap bitmap) {
         try {
             Matrix matrix = new Matrix();
-            if (ConfigValues.bSmartIOTCamFlip || !(Build.VERSION.SDK_INT > 23)) matrix.setScale(-1, 1);
+            if (ConfigValues.bSmartIOTCamFlip) matrix.setScale(-1, 1);
             else matrix.setScale(1, 1);
             return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
         } catch (RuntimeException re) {
@@ -3886,7 +3991,7 @@ public class MainActivity extends WpadActivity {
                     Result = Bitmap.createBitmap(Result, 5, 5, nFixedIMGSize_Width, nFixedIMGSize_Height);
                     Result = reverseIMGColor(Result);
                     if (ConfigValues.eFrontCameraType == FRONTCAMERATYPE.SMARTIOT || ConfigValues.eFrontCameraType == FRONTCAMERATYPE.HD) {
-                        // 스마트IoT현관카메라의 경우 사진 좌우반전 옵션 확인하여 좌우반전 수행
+                        // 스마트IoT현관카메라의 경우 사진 색반전 코드 적용 (JEFF, 2020.08.11)
                         Result = flipTakenIMG(Result);
                     }
                 }
@@ -3900,11 +4005,6 @@ public class MainActivity extends WpadActivity {
                 else {
                     Result = getResizedBitmap(Original, nFixedIMGSize_Width + 5, nFixedIMGSize_Height + 5);
                     Result = Bitmap.createBitmap(Result, 5, 5, nFixedIMGSize_Width, nFixedIMGSize_Height);
-
-                    if (ConfigValues.eFrontCameraType == FRONTCAMERATYPE.SMARTIOT || ConfigValues.eFrontCameraType == FRONTCAMERATYPE.HD) {
-                        // 스마트IoT현관카메라의 경우 사진 좌우반전 옵션 확인하여 좌우반전 수행
-                        Result = flipTakenIMG(Result);
-                    }
                 }
             }
 
@@ -4470,8 +4570,8 @@ public class MainActivity extends WpadActivity {
 
                 case HANDLERMSG.SET_TALK_BTN_ENABLE:
                     Log.d(TAG, "[MainHandler] SET_TALK_BTN_ENABLE");
-                    if (TalkFront.BTN_TALK != null) TalkFront.BTN_TALK.setButtonEventOffDisable();
-                    else Log.w(TAG, "[MainHandler] TalkFront.BTN_TALK is null!! -> HANDLERMSG.SET_TALK_BTN_ENABLE");
+//                    if (TalkFront.BTN_TALK != null) TalkFront.BTN_TALK.setButtonEventOffDisable();
+//                    else Log.w(TAG, "[MainHandler] TalkFront.BTN_TALK is null!! -> HANDLERMSG.SET_TALK_BTN_ENABLE");
                     break;
 
                 case HANDLERMSG.REFRESH_HOMEICON:
@@ -4720,6 +4820,7 @@ public class MainActivity extends WpadActivity {
                 String strAction = intent.getAction();
                 Log.d(this.TAG, "[onReceive] strAction [" + strAction + "]");
                 if (strAction.equals(Declare.BR.APP_FINISH)) {
+                    mIOInterface.ctrlPopupGUI(true);
                     mCallController.setTalkPath(CALLPATH.NORMAL); // Finish BR 수신시 통화패스 Normal로 변경
                     if (mMainEventListener != null) {
                         String strCallOwner = intent.getStringExtra(CALLTRIGGER.CALLOWNER);

+ 162 - 5
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/declare/DataClasses.java

@@ -1715,18 +1715,97 @@ public final class DataClasses {
     }
 
     // 통화 내역 데이터 테이블
+    public static class AllCallHistoryInfoTable {
+        private ArrayList<AllCallHistoryInfo> AllCallHistoryInfoTables = new ArrayList<AllCallHistoryInfo>();
+//params event_time="0001.01.01.00.00.00" call_type="missed_call" send_device="homedev" send_id_high="101" send_id_low="101" recv_device="lobby" recv_id_high="101" recv_id_low="101" message="null"
+        public class AllCallHistoryInfo {
+            private String event_time = "";
+            private String call_type = ""; //send_device
+            private String send_device = ""; //call_type
+            private String send_id_high = ""; //recv_device
+            private String send_id_low = ""; //recv_id_high recv_id_low
+            private String recv_device = "";
+            private String recv_id_high = "";
+            private String recv_id_low = ""; //event_time
+            private String message = "";
+            private String mData = "";
+
+            public AllCallHistoryInfo(String strEvent_time, String strCall_type, String strSend_device, String strSend_id_high, String strSend_id_low, String strRecv_device, String strRecv_id_high, String strRecv_id_low, String strMessage) {
+                event_time = strEvent_time;
+                call_type = strCall_type;
+                send_device = strSend_device;
+                send_id_high = strSend_id_high;
+                send_id_low = strSend_id_low;
+                recv_device = strRecv_device;
+                recv_id_high = strRecv_id_high;
+                recv_id_low = strRecv_id_low;
+                message = strMessage;
+                mData = "<params event_time=\"" + event_time + "\" " +
+                        "call_type=\"" + call_type + "\" " +
+                        "send_device=\"" + send_device + "\" " +
+                        "send_id_high=\"" + send_id_high + "\" " +
+                        "send_id_low=\"" + send_id_low + "\" " +
+                        "recv_device=\"" + recv_device + "\" " +
+                        "recv_id_high=\"" + recv_id_high + "\" " +
+                        "recv_id_low=\"" + recv_id_low + "\" " +
+                        "message=\"" + message + "\"></params>";
+            }
+
+            public String getData() {
+        return mData;
+    }
+
+        }
+
+
+
+        public void addCallHistoryInfo(String strEvent_time, String strCall_type, String strSend_device, String strSend_id_high, String strSend_id_low, String strRecv_device, String strRecv_id_high, String strRecv_id_low, String strMessage) {
+            AllCallHistoryInfo NewCallHistoryInfo = new AllCallHistoryInfo(strEvent_time, strCall_type, strSend_device, strSend_id_high, strSend_id_low, strRecv_device, strRecv_id_high, strRecv_id_low, strMessage);
+            AllCallHistoryInfoTables.add(NewCallHistoryInfo);
+        }
+
+        public void removeCallHistoryInfo(int nIndex) {
+            AllCallHistoryInfoTables.remove(nIndex);
+        }
+
+        public AllCallHistoryInfo getCallHistoryInfo(int nIndex) {
+            if (getCnt() < nIndex) return null;
+            return (AllCallHistoryInfo) AllCallHistoryInfoTables.get(nIndex);
+        }
+
+        public void printValue() {
+            for (int i = 0; i < AllCallHistoryInfoTables.size(); i++) {
+                AllCallHistoryInfo item = getCallHistoryInfo(i);
+//                if(item!=null)
+//                {
+//                    LOG("[CallHistoryInfoTable] sID [" + item.getID() + "], sName [" + item.getName() + "], sCallResult [" + item.getCallResult() + "], sRemoteIP [" + item.getRemoteIP() + "], " +
+//                            "sSIPID [" + item.getSIPID() + "], sChecked [" + item.getChecked() + "], sETC [" + item.getETC() + "], sTimestamp [" + item.getTimestamp() + "]");
+//                }
+
+            }
+        }
+
+        public int getCnt() {
+            return AllCallHistoryInfoTables.size();
+        }
+
+        public void clearTable() {
+            AllCallHistoryInfoTables.clear();
+        }
+    }
+
     public static class CallHistoryInfoTable {
         private ArrayList<CallHistoryInfo> CallHistoryInfoTables = new ArrayList<CallHistoryInfo>();
 
         public class CallHistoryInfo {
             private String strID = "";
-            private String strName = "";
-            private String strCallResult = "";
-            private String strRemoteIP = "";
-            private String strSIPID = "";
+            private String strName = ""; //send_device
+            private String strCallResult = ""; //call_type
+            private String strRemoteIP = ""; //recv_device
+            private String strSIPID = ""; //recv_id_high recv_id_low
             private String strChecked = "";
             private String strETC = "";
-            private String strTimestamp = "";
+            private String strTimestamp = ""; //event_time
 
             public CallHistoryInfo(String sID, String sName, String sCallResult, String sRemoteIP, String sSIPID, String sChecked, String sETC, String sTimestamp) {
                 strID = sID;
@@ -1882,6 +1961,84 @@ public final class DataClasses {
         }
     }
 
+    public static class AllVisitorPictureHistoryInfoTable {
+        private ArrayList<AllVisitorPictureHistoryInfo> AllVisitorPictureHistoryInfoTables = new ArrayList<AllVisitorPictureHistoryInfo>();
+
+        public class AllVisitorPictureHistoryInfo {
+            private String dong = "";
+            private String ho = "";
+            private String time = "";
+            private String path = "";
+            private String filename = "";
+            private String message = "";
+            private String strData = "";
+
+            public AllVisitorPictureHistoryInfo(String strDong, String strHo, String strTime, String strPath, String strFilename, String strMessage) {
+                dong = strDong;
+                ho = strHo;
+                time = strTime;
+                path = strPath;
+                filename = strFilename;
+                message = strMessage;
+
+                strData = "<visitor_pic dong= \"" + strDong + "\" " +
+                        "ho= \"" + strHo + "\" " +
+                        "time= \"" + strTime + "\" " +
+                        "path=\"" + strPath + "\" " +
+                        "filename = \"" + strFilename + "\" " +
+                        "message= \"" + strMessage + "\"/>";
+
+            }
+
+            public String getData() {
+                return strData;
+            }
+            public String getPath() {
+                return path;
+            }
+            public String getFilename() {
+                return filename;
+            }
+
+        }
+
+        public void addVisitorPictureHistoryInfo(String strDong, String strHo, String strTime, String strPath, String strFilename, String strMessage) {
+            AllVisitorPictureHistoryInfo NewVisitorPictureHistoryInfo = new AllVisitorPictureHistoryInfo(strDong, strHo, strTime, strPath, strFilename, strMessage);
+            AllVisitorPictureHistoryInfoTables.add(NewVisitorPictureHistoryInfo);
+        }
+
+        public void removeVisitorPictureHistoryInfo(int nIndex) {
+            AllVisitorPictureHistoryInfoTables.remove(nIndex);
+        }
+
+        public AllVisitorPictureHistoryInfo getVisitorPictureHistoryInfo(int nIndex) {
+            if (getCnt() < nIndex) return null;
+            return (AllVisitorPictureHistoryInfo) AllVisitorPictureHistoryInfoTables.get(nIndex);
+        }
+
+        public void printValue() {
+            for (int i = 0; i < AllVisitorPictureHistoryInfoTables.size(); i++) {
+                AllVisitorPictureHistoryInfo item = getVisitorPictureHistoryInfo(i);
+                if(item!=null)
+                {
+//                    LOG("[CallHistoryInfoTable] ID [" + item.getID() + "], Name [" + item.getName() + "], RemoteSIPID [" + item.getRemoteSIPID() + "], " +
+//                            "Checked [" + item.getChecked() + "], Thief [" + item.getThief() + "], " +
+//                            "URI [" + item.getURI() + "], ETC [" + item.getETC() + "], " +
+//                            "Timestamp [" + item.getTimestamp() + "]");
+                }
+
+            }
+        }
+
+        public int getCnt() {
+            return AllVisitorPictureHistoryInfoTables.size();
+        }
+
+        public void clearTable() {
+            AllVisitorPictureHistoryInfoTables.clear();
+        }
+    }
+
     // 방문자 사진 데이터 테이블
     public static class VisitorPictureHistoryInfoTable {
         private ArrayList<VisitorPictureHistoryInfo> VisitorPictureHistoryInfoTables = new ArrayList<VisitorPictureHistoryInfo>();

+ 7 - 1
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/declare/Global.java

@@ -2730,8 +2730,14 @@ public final class Global {
             else {
                 String[] IP_Parse = strIPAddress.split("\\.");
                 if (IP_Parse[2].equals("128")) return CALLTYPE.GUARD;
-                else if (IP_Parse[2].equals("0")) return CALLTYPE.LOBBY;
+                else if (IP_Parse[2].equals("0"))
+                {
+                    if(IP_Parse[3].equals("11"))
+                        return CALLTYPE.FRONT;
+                    return CALLTYPE.LOBBY;
+                }
                 else if (IP_Parse[2].equals("201")) return CALLTYPE.IHUB;
+                else if (IP_Parse[2].equals("129")) return CALLTYPE.FRONT;
                 else return CALLTYPE.RESIDENCE;
             }
         } catch (RuntimeException re) {

+ 153 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_delete.java

@@ -0,0 +1,153 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_call_history_delete extends WallPadiMAPClient {
+    String TAG = "Request_call_history_delete";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.1";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_call_history_delete(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_delete(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strMsg, String strCount) {
+        try {
+            //<homeaddr name = "homedev" id_high = "102" id_low = "301" />
+            //<call_type> "all" </call_type>
+            //<count> "30" </count >
+
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"call_history_delete\">\r\n" +
+                    //"      <visitor_info dong=\"" + strDong + "\" ho=\"" + strHo + "\" distinct=\"" + strType + "\" time=\"" + strTime + "\" filename=\"" + strFileName + "\" message=\"" + strMessage + "\"/>\r\n" +
+                    "       <homeaddr name = \"homedev\" id_high = \"" + DeviceDong + "\" id_low = \"" + DeviceHo + "\" />\r\n" +
+                    "       <count> \"" + strCount + "\" </count>\r\n" +
+                    strMsg +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name= GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("call_history_delete")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_call_history_delete(String strMsg, String strCount) {
+        try {
+            SetServerIPConfig(svrIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strMsg, strCount), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_delete(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 153 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_inquiry.java

@@ -0,0 +1,153 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_call_history_inquiry extends WallPadiMAPClient {
+    String TAG = "Request_call_history_inquiry";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.1";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_call_history_inquiry(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_inquiry(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strDong, String strHo, String strType, String strCount) {
+        try {
+            //<homeaddr name = "homedev" id_high = "102" id_low = "301" />
+            //<call_type> "all" </call_type>
+            //<count> "30" </count >
+
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"call_history_inquiry\">\r\n" +
+                    //"      <visitor_info dong=\"" + strDong + "\" ho=\"" + strHo + "\" distinct=\"" + strType + "\" time=\"" + strTime + "\" filename=\"" + strFileName + "\" message=\"" + strMessage + "\"/>\r\n" +
+                    "       <homeaddr name = \"homedev\" id_high = \"" + strDong + "\" id_low = \"" + strHo + "\" />\r\n" +
+                    "       <call_type> \"" + strType + "\" </call_type>\r\n" +
+                    "       <count> \"" + strCount + "\" </count>\r\n" +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name= GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("call_history_inquiry")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_call_history_inquiry(String strDong, String strHo, String strPage, String strCount) {
+        try {
+            SetServerIPConfig(svrIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strDong, strHo, strPage, strCount), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_inquiry(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 153 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_call_history_save.java

@@ -0,0 +1,153 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_call_history_save extends WallPadiMAPClient {
+    String TAG = "Request_call_history_save";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.1";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_call_history_save(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_save(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strDong, String strHo, String strType, String time) {
+        try {
+            //<homeaddr name = "homedev" id_high = "102" id_low = "301" />
+            //<call_type> "all" </call_type>
+            //<count> "30" </count >
+
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"call_history_save\">\r\n" +
+                    //"      <visitor_info dong=\"" + strDong + "\" ho=\"" + strHo + "\" distinct=\"" + strType + "\" time=\"" + strTime + "\" filename=\"" + strFileName + "\" message=\"" + strMessage + "\"/>\r\n" +
+                    "       <homeaddr name = \"homedev\" id_high = \"" + DeviceDong + "\" id_low = \"" + DeviceHo + "\" />\r\n" +
+                    "       <call_type> \"" + strType + "\" </call_type>\r\n" +
+                    "       <params event_time = \"" + time + "\" device=\"homedev\" id_high=\"" + strDong + "\" id_low=\"" + strHo + "\" />\r\n" +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name= GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("call_history_save")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_call_history_save(String strDong, String strHo, String strPage, String strTime) {
+        try {
+            SetServerIPConfig(svrIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strDong, strHo, strPage, strTime), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_call_history_save(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 146 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_lobby_capture.java

@@ -0,0 +1,146 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_lobby_capture extends WallPadiMAPClient {
+    String TAG = "Request_lobby_open";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.10";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_lobby_capture(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_lobby_capture(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strMessage) {
+        try {
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"lobby_capture\"/>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name = GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("lobby_open")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_lobby_capture(String strTargetIP, String strMessage) {
+        try {
+//            if(((MainActivity) mContext).mNewDanjiServer)
+//                svrPort = svrPort + 1000;
+            SetServerIPConfig(strTargetIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strMessage), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_lobby_open(String strTargetIP, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 131 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_start_talking.java

@@ -0,0 +1,131 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadDeviceSet;
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+
+import kr.co.icontrols.wallpadcall.MainActivity;
+
+public class Request_start_talking extends WallPadiMAPClient {
+    String TAG = "Request_start_talking";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.10";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_start_talking(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_start_talking(Context context)");
+            e.printStackTrace();
+        }
+    }
+
+    private String makeXMLMsg(String strMessage) {
+        try {
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"start_talking\" >\r\n" +
+                    "   <calltype>\"lobby\"</calltype>\r\n" +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strMessage)");
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            e.printStackTrace();
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            e.printStackTrace();
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        if ((GetAttributeVal(0, "name").equalsIgnoreCase("start_talking")) && (GetAttributeVal(0, "type").equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                Proc.ProcError();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            e.printStackTrace();
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_start_talking(String strTargetIP, String strMessage) {
+        try {
+
+            int port = 10000;
+//            if(((MainActivity) mContext).mNewDanjiServer)
+//                port = svrPort + 1000;
+
+            SetServerIPConfig(strTargetIP, port);
+            SendXMLDoc(makeXMLMsg(strMessage), true);
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_start_talking(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+            return false;
+        }
+    }
+}

+ 129 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_stop_talking.java

@@ -0,0 +1,129 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+
+import kr.co.icontrols.wallpadcall.MainActivity;
+
+public class Request_stop_talking extends WallPadiMAPClient {
+    String TAG = "Request_stop_talking";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.10";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_stop_talking(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_stop_talking(Context context)");
+            e.printStackTrace();
+        }
+    }
+
+    private String makeXMLMsg(String strMessage) {
+        try {
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"stop_talking\" >\r\n" +
+                    "   <calltype>\"lobby\"</calltype>\r\n" +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strMessage)");
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            e.printStackTrace();
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            e.printStackTrace();
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        if ((GetAttributeVal(0, "name").equalsIgnoreCase("stop_talking")) && (GetAttributeVal(0, "type").equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        } else{
+
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                Proc.ProcError();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            e.printStackTrace();
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_stop_talking(String strTargetIP, String strMessage) { //xml 보내는 부분
+        try {
+//            if(((MainActivity) mContext).mNewDanjiServer)
+//                svrPort = svrPort + 1000;
+            SetServerIPConfig(strTargetIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strMessage),true);
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_stop_talking(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+            return false;
+        }
+    }
+}

+ 153 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_visitor_picture_delete.java

@@ -0,0 +1,153 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_visitor_picture_delete extends WallPadiMAPClient {
+    String TAG = "Request_visitor_picture_delete";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.1";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_visitor_picture_delete(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_visitor_picture_delete(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strMsg, String strCount) {
+        try {
+            //<homeaddr name = "homedev" id_high = "102" id_low = "301" />
+            //<call_type> "all" </call_type>
+            //<count> "30" </count >
+
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"visitor_picture_delete\">\r\n" +
+                    //"      <visitor_info dong=\"" + strDong + "\" ho=\"" + strHo + "\" distinct=\"" + strType + "\" time=\"" + strTime + "\" filename=\"" + strFileName + "\" message=\"" + strMessage + "\"/>\r\n" +
+                    "       <homeaddr name = \"homedev\" id_high = \"" + DeviceDong + "\" id_low = \"" + DeviceHo + "\" />\r\n" +
+                    "       <count> \"" + strCount + "\" </count>\r\n" +
+                    strMsg +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name= GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("visitor_picture_delete")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_visitor_picture_delete(String strMsg, String strCount) {
+        try {
+            SetServerIPConfig(svrIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strMsg, strCount), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_visitor_picture_delete(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 152 - 0
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/imap/Request_visitor_picture_inquiry.java

@@ -0,0 +1,152 @@
+package kr.co.icontrols.wallpadcall.imap;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.artncore.WallPadDataMgr.WallpadStatusData;
+import com.artncore.WallPadDataMgr.wallpaddbmgr.AddressSet;
+import com.artncore.wallpadimap.RetProci;
+import com.artncore.wallpadimap.WallPadiMAPClient;
+import com.util.LogUtil;
+
+public class Request_visitor_picture_inquiry extends WallPadiMAPClient {
+    String TAG = "Request_visitor_picture_inquiry";
+    String DeviceIP = "NONE";
+    String DeviceDong = "NONE";
+    String DeviceHo = "NONE";
+
+    Context mContext;
+    RetProci Proc;
+    String XMLHeader;
+    WallpadStatusData DBMGR = null;
+
+    String svrIP = "10.0.1.1";
+    int svrPort = 10000;
+    int RequestWork = 0;
+
+    public Request_visitor_picture_inquiry(Context context) {
+        super.setContext(context);
+        try {
+            mContext = context;
+            super.setContext(mContext);
+            DBMGR = new WallpadStatusData(mContext);
+            AddressSet Address = DBMGR.getAddressMGR(); //DB에서 동호 정보 받아옴
+            DBMGR.closeDB();
+            //동, 호, ip 정보 저장
+            DeviceIP = Address.IPAddress;
+            DeviceDong = Address.Dong;
+            DeviceHo = Address.Ho;
+
+            //타임아웃 설정
+            SetSocketWaitCount(2000);
+
+            //XML Header 생성
+            XMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
+                    "<imap ver = \"1.0\" address = \"" + DeviceIP + "\" sender = \"" + DeviceDong + "동 " + DeviceHo + "호" + "\">\r\n";
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] Request_visitor_picture_inquiry(Context context)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    private String makeXMLMsg(String strDong, String strHo, String strPage, String strCount) {
+        try {
+            //<service type="request" name="visitor_picture_inquiry">
+            //<homeaddr name = "homedev" id_high = "102" id_low = "301" />
+            //<inquiry_info start_num="1" quantity="6" />
+
+            String strResult = XMLHeader +
+                    "   <service type=\"request\" name=\"visitor_picture_inquiry\">\r\n" +
+                    //"      <visitor_info dong=\"" + strDong + "\" ho=\"" + strHo + "\" distinct=\"" + strType + "\" time=\"" + strTime + "\" filename=\"" + strFileName + "\" message=\"" + strMessage + "\"/>\r\n" +
+                    "       <homeaddr name = \"homedev\" id_high = \"" + strDong + "\" id_low = \"" + strHo + "\" />\r\n" +
+                    "       <inquiry_info start_num=\"" + strPage + "\" quantity=\"" + strCount + "\" />\r\n" +
+                    "   </service>\r\n" +
+                    "</imap>";
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeXMLMsg(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    public void setServerInfo(String strIPAddress, int nPort) {
+        try {
+            svrIP = strIPAddress;
+            svrPort = nPort;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setServerInfo(String strIPAddress, int nPort)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    public void setResultCtrl(RetProci retProci) {
+        try {
+            Proc = retProci;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] setResultCtrl(RetProci retProci)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcComplite() {
+        try {
+            if (Proc != null) {
+                SetItem("service");
+                String result = GetAttributeVal(0, "result");
+                if (result != null) {
+                    if (result.equalsIgnoreCase("ok")) {
+                        String name= GetAttributeVal(0, "name");
+                        String type = GetAttributeVal(0, "type");
+                        if ((name!=null && name.equalsIgnoreCase("visitor_picture_inquiry")) && (type!=null && type.equalsIgnoreCase("reply"))) {
+                            Proc.ProcSuccess();
+                            return;
+                        }
+                    }
+                }
+                Proc.ProcError();
+            } else {
+                if(Proc!=null) Proc.ProcError();
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] ProcComplite()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+
+    protected void ProcError() {
+        Proc.ProcError();
+    }
+
+    public boolean send_visitor_picture_inquiry(String strDong, String strHo, String strPage, String strCount) {
+        try {
+            SetServerIPConfig(svrIP, svrPort);
+            SendXMLDoc(makeXMLMsg(strDong, strHo, strPage, strCount), true);
+            return true;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_visitor_picture_inquiry(String strDong, String strHo, String strType, String strTime, String strFileName, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+}

+ 238 - 52
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/InquiryCallHistory.java

@@ -10,6 +10,7 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.widget.RelativeLayout;
 
+import com.artncore.wallpadimap.RetProci;
 import com.util.LogUtil;
 
 import java.util.ArrayList;
@@ -23,7 +24,9 @@ import kr.co.icontrols.wallpadcall.MainActivity.MAINEVENT;
 import kr.co.icontrols.wallpadcall.MainActivity.MainEventListener;
 import kr.co.icontrols.wallpadcall.R;
 import kr.co.icontrols.wallpadcall.declare.Common;
+import kr.co.icontrols.wallpadcall.declare.DataClasses;
 import kr.co.icontrols.wallpadcall.declare.DataClasses.CallHistoryInfoTable;
+import kr.co.icontrols.wallpadcall.declare.DataClasses.AllCallHistoryInfoTable;
 import kr.co.icontrols.wallpadcall.declare.Declare;
 import kr.co.icontrols.wallpadcall.declare.Declare.DEVICENAME;
 import kr.co.icontrols.wallpadcall.declare.Declare.DeviceType;
@@ -31,6 +34,9 @@ import kr.co.icontrols.wallpadcall.declare.Global;
 import kr.co.icontrols.wallpadcall.declare.Global.CALLRESULT;
 import kr.co.icontrols.wallpadcall.declare.Global.ConfigValues;
 import kr.co.icontrols.wallpadcall.declare.ID;
+import kr.co.icontrols.wallpadcall.imap.Request_call_history_delete;
+import kr.co.icontrols.wallpadcall.imap.Request_call_history_inquiry;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_inquiry;
 import kr.co.icontrols.wallpadsupport.WpadImageView;
 import kr.co.icontrols.wallpadsupport.WpadImageView.TOUCH_KIND;
 import kr.co.icontrols.wallpadsupport.WpadScreen;
@@ -79,6 +85,8 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
     static int LIST_CNT_EASYMODE = 3; // 간편모드UX 적용할 경우
 
     LIST[] mLIST = new LIST[LIST_CNT];
+    CallHistoryInfoTable mInfoTable = new CallHistoryInfoTable();
+    AllCallHistoryInfoTable mAllInfoTable = new AllCallHistoryInfoTable();
 
     class LIST {
         WpadImageView BTN_CHECK;
@@ -221,7 +229,7 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
 
                 nViewGuide_Y += 90 + idx * 90;
             }
-            getHistoryFromDB();
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -244,6 +252,7 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
             if (ConfigValues.bEasyModeUse) LIST_CNT = LIST_CNT_EASYMODE;
 
             initHistoryPageInfo();
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -417,17 +426,22 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CONFIRM");
                     if (strItemType.equals("CallHistoryItems_All")) {
                         deleteAllItems();
-                        getHistoryFromDB();
+                        deleteSelectedItems();
+                        resetCheckBox();
+                        initHistoryPageInfo();
+                        //getHistoryFromDB();
                     } else if (strItemType.equals("CallHistoryItems")) {
                         deleteSelectedItems();
                         resetCheckBox();
                         initHistoryPageInfo();
-                        getHistoryFromDB();
+                        //send_call_history_inquiry("all", "60");
+                        //getHistoryFromDB();
                     }
                 } else if (nID == ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL) {
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL");
                     resetCheckBox();
-                    getHistoryFromDB();
+
+                    //getHistoryFromDB();
                 }
             }
         } catch (RuntimeException re) {
@@ -439,6 +453,79 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
         }
     }
 
+    private boolean send_call_history_inquiry(String strType, String strCount) {
+        try {
+            LOG_INFO("[send_call_history_inquiry] strType() "+ strType + " strCount " + strCount);
+            final Request_call_history_inquiry call_history_inquiry = new Request_call_history_inquiry(mContext);
+            if (call_history_inquiry.send_call_history_inquiry("101", "101", strType, strCount)) {
+                call_history_inquiry.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+
+                        LOG_INFO("[send_call_history_inquiry] ProcSuccess() ");
+
+                        call_history_inquiry.SetItem("count");
+                        nHistoryCnt = Integer.parseInt(call_history_inquiry.GetItemVal(0));
+                        LOG("[send_call_history_inquiry] nHistoryCnt = " + nHistoryCnt);
+                        nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+                        call_history_inquiry.SetItem("params");
+
+                        mInfoTable.clearTable();
+                        mAllInfoTable.clearTable();
+                        for(int i = 0; i < nHistoryCnt; i++)
+                        {
+                            //LOG_INFO("[send_call_history_inquiry] " + i + " " + call_history_inquiry.GetAttributeVal(i, "event_time"));
+                            String strName = call_history_inquiry.GetAttributeVal(i, "send_device");
+                            String strCallResult = call_history_inquiry.GetAttributeVal(i, "call_type");
+                            String strRemoteIP = call_history_inquiry.GetAttributeVal(i, "recv_device");
+                            String strSIPID = call_history_inquiry.GetAttributeVal(i, "recv_id_high") + "동" + call_history_inquiry.GetAttributeVal(i, "recv_id_low") + "호";
+                            String strTimestamp = call_history_inquiry.GetAttributeVal(i, "event_time");
+
+                            mInfoTable.addCallHistoryInfo("", strName, strCallResult, strRemoteIP, strSIPID, "", "", strTimestamp);
+
+                            mAllInfoTable.addCallHistoryInfo(call_history_inquiry.GetAttributeVal(i, "event_time"),
+                                    call_history_inquiry.GetAttributeVal(i, "call_type"),
+                                    call_history_inquiry.GetAttributeVal(i, "send_device"),
+                                    call_history_inquiry.GetAttributeVal(i, "send_id_high"),
+                                    call_history_inquiry.GetAttributeVal(i, "send_id_low"),
+                                    call_history_inquiry.GetAttributeVal(i, "recv_device"),
+                                    call_history_inquiry.GetAttributeVal(i, "recv_id_high"),
+                                    call_history_inquiry.GetAttributeVal(i, "recv_id_low"),
+                                    call_history_inquiry.GetAttributeVal(i, "message")
+                                    );
+
+                        }
+
+
+                        getHistoryFromDB();
+//                        visitor_picture_inquiry.SetItem("ftp_info");
+//                        strReply_User = visitor_access_info.GetAttributeVal(0, "user");
+//                        strReply_PW = visitor_access_info.GetAttributeVal(0, strPass_Key);
+//                        strReply_Path = visitor_access_info.GetAttributeVal(0, "path");
+                        //MainActivity.mCallController.mSIPInterface.requestCallForwardToStun(MainActivity.mCallController.makeCallForwarInfo(strTargetIP));
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_call_history_inquiry] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_call_history_inquiry] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_call_history_inquiry(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
     boolean bProcessing = false;
 
     private boolean tryAutoCall(int nSelectedItem) {
@@ -574,18 +661,11 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
 
     private String makeUnitTimestamp(String strTimestamp) {
         try {
-//            LOG("[makeUnitTimestamp] strTimestamp = " + strTimestamp);
-            String[] strParse_01 = strTimestamp.split(" ");
-//            LOG_DEBUG("[makeUnitTimestamp] strParse_01.length = " + strParse_01.length);
+            String strResult = "";
 
-            String strDate = strParse_01[0].replace("-", ".");
-//            LOG_DEBUG("[makeUnitTimestamp] strDate = " + strDate);
-            String[] strParse_02 = strParse_01[1].split(":");
-//            LOG_DEBUG("[makeUnitTimestamp] strParse_02.length = " + strParse_02.length);
+            String[] strSplit = strTimestamp.split("\\.");
 
-            String strTime = strParse_02[0] + ":" + strParse_02[1];
-            String strResult = strDate + " " + strTime;
-            LOG("[makeUnitTimestamp] strResult = " + strResult);
+            strResult = strSplit[0] + "." + strSplit[1] + "." + strSplit[2] + " " + strSplit[3] + ":" + strSplit[4];
             return strResult;
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -598,15 +678,57 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
         }
     }
 
+    private String makeResiType(String strResultType) {
+        try {
+            LOG("[makeResiType] strResultType = " + strResultType);
+            String strResult = "NONE";
+            if (strResultType.contains("101호")) {
+                strResult = "1층";
+            }
+            else if (strResultType.contains("201호")) {
+                strResult = "2층";
+            }
+            else if (strResultType.contains("301호")) {
+                strResult = "3층";
+            }
+            else if (strResultType.contains("102호")) {
+                strResult = "메이드";
+            }
+            else if (strResultType.contains("103호")) {
+                strResult = "기사";
+            }
+            else if (strResultType.contains("302호")) {
+                strResult = "안방";
+            }
+            else if (strResultType.contains("202호")) {
+                strResult = "주방";
+            }else
+            {
+                strResult = "";
+            }
+
+            LOG("[makeUnitType] strResult = " + strResult);
+            return strResult;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return "ERROR";
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] makeUnitType(strResultType) : " + e);
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return "ERROR";
+        }
+    }
+
     private String makeUnitType(String strResultType) {
         try {
             LOG("[makeUnitType] strResultType = " + strResultType);
             String strResult = "NONE";
-            if (strResultType.equalsIgnoreCase(CALLRESULT.IN_MISS.toString())) {
+            if (strResultType.equalsIgnoreCase("missed_call")) {
                 strResult = "부재중";
             } else if (strResultType.equalsIgnoreCase(CALLRESULT.OUT_MISS.toString())) {
                 strResult = "발신";
-            } else if (strResultType.equalsIgnoreCase(CALLRESULT.IN_TALK.toString())) {
+            } else if (strResultType.equalsIgnoreCase("call")) {
                 strResult = "수신";
             } else if (strResultType.equalsIgnoreCase(CALLRESULT.IN_TALK_DOOR.toString())) {
                 strResult = "수신";
@@ -616,7 +738,7 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
                 strResult = "발신";
             } else if (strResultType.equalsIgnoreCase(CALLRESULT.OUT_HONEVIEW.toString())) {
                 strResult = "발신";
-            } else if (strResultType.equalsIgnoreCase(CALLRESULT.IN_REJECT.toString())) {
+            } else if (strResultType.equalsIgnoreCase("reject_call")) {
                 strResult = "수신(거절)";
             } else if (strResultType.equalsIgnoreCase(CALLRESULT.OUT_REJECT.toString())) {
                 strResult = "발신";
@@ -664,14 +786,21 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
 
     private void deleteSelectedItems() {
         try {
+            int iListCount = (nCurrentPage-1) * 6;
+            int iCount = 0;
+            String strMsg = "";
             ArrayList<String> SelectedIDs = new ArrayList<String>();
             for (int i = 0; i < nActivatedListCnt; i++) {
                 if (mLIST_VALUE[i].CHECK) {
-                    SelectedIDs.add(mLIST_VALUE[i].ID);
+                    strMsg += mAllInfoTable.getCallHistoryInfo(i + iListCount).getData() + "\r\n";
+                    iCount++;
+                    //SelectedIDs.add(mLIST_VALUE[i].ID);
                 }
                 mLIST_VALUE[i].CHECK = false;
             }
-            MainActivity.mCallHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_CALL, SelectedIDs);
+
+            send_call_history_delete(strMsg, String.valueOf(iCount));
+            //MainActivity.mCallHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_CALL, SelectedIDs);
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -681,10 +810,42 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
         }
     }
 
+    private boolean send_call_history_delete(String strMsg, String strCount) {
+        try {
+            LOG_INFO("[send_call_history_inquiry] strType() "+ strMsg + " strCount " + strCount);
+            final Request_call_history_delete call_history_delete = new Request_call_history_delete(mContext);
+            if (call_history_delete.send_call_history_delete(strMsg, strCount)) {
+                call_history_delete.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+
+                        LOG_INFO("[send_call_history_delete] ProcSuccess() ");
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_call_history_delete] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_call_history_delete] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_call_history_delete(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
     private void deleteAllItems() {
         try {
-            MainActivity.mCallHistoryManager.deleteDBFile();
-            MainActivity.mCallHistoryManager.initCallHistory(mContext);
+            send_call_history_delete("", "all");
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -800,17 +961,13 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
 
     private String getNameImgText(String strIPAddress) {
         try {
-            CALLTYPE eCallType = Global.getCallType(strIPAddress);
+            //CALLTYPE eCallType = Global.getCallType(strIPAddress);
 
-            if (eCallType == CALLTYPE.FRONT) return "현관";
-            else if (eCallType == CALLTYPE.LOBBY)
+            if (strIPAddress.equals("front")) return "현관";
+            else if (strIPAddress.equals("lobby"))
                 return "로비";
-            else if (eCallType == CALLTYPE.GUARD)
-                return "경비";
-            else if (eCallType == CALLTYPE.RESIDENCE)
+            else if (strIPAddress.equals("homedev"))
                 return "이웃";
-            else if (eCallType == CALLTYPE.PSTN)
-                return "전화";
             else return "경비실";
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -826,6 +983,7 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
     private boolean activateTalkBTN(String strName) {
         try {
             if (strName.contains("로비")) return false;
+            else if (strName.contains("현관")) return false;
             else if (strName.contains("발신번호 없음")) return false;
             else if (strName.contains("발신번호제한")) return false;
             else if (strName.contains("번호정보없음")) return false;
@@ -842,6 +1000,8 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
         }
     }
 
+
+
     private void getHistoryFromDB() {
         try {
             LOG_DEBUG("[getHistoryFromDB] nCurrentPage = " + nCurrentPage + ", nTotalPage = " + nTotalPage);
@@ -861,11 +1021,12 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
             if (nStartIndex + (LIST_CNT - 1) > nHistoryCnt) {
                 nCnt = LIST_CNT - ((nStartIndex + (LIST_CNT - 1)) - nHistoryCnt);
             }
-            CallHistoryInfoTable InfoTable = new CallHistoryInfoTable();
-            InfoTable.clearTable();
-            InfoTable = MainActivity.mCallHistoryManager.getCallHistory(nStartIndex - 1, nCnt);
-            LOG_DEBUG("[getHistoryFromDB] nStartIndex = " + nStartIndex + ", nCnt = " + nCnt);
-            if (InfoTable == null) {
+
+//            CallHistoryInfoTable InfoTable = new CallHistoryInfoTable();
+//            InfoTable.clearTable();
+//            InfoTable = MainActivity.mCallHistoryManager.getCallHistory(nStartIndex - 1, nCnt);
+//            LOG_DEBUG("[getHistoryFromDB] nStartIndex = " + nStartIndex + ", nCnt = " + nCnt);
+            if (nHistoryCnt == 0) {
                 BTN_DELETE.setButtonEventOffEnable(R.drawable.btn_ch_del_disabled);
                 BTN_DELETE_ALL.setButtonEventOffEnable(R.drawable.btn_ch_all_del_disabled);
                 BTN_PAGE_PREV.setButtonEventOffEnable(R.drawable.btn_back_disabled);
@@ -881,19 +1042,40 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
 //                BTN_PAGE_NEXT.setButtonEventOffEnable(R.drawable.btn_next_disabled);
 //            }
 
-            int nInfoCnt = InfoTable.getCnt();
+            int nInfoCnt = 0;
+
+            int iListCount = (nCurrentPage-1) * 6;
+
+            if (nCurrentPage == nTotalPage)
+            {
+                nInfoCnt = nHistoryCnt - iListCount;
+            }
+            else
+                nInfoCnt = 6;
+
+
             nActivatedListCnt = nInfoCnt;
+
+
             LOG_DEBUG("[getHistoryFromDB] nInfoCnt = " + nInfoCnt);
+            LOG_DEBUG("[getHistoryFromDB] iListCount = " + iListCount);
             for (int i = 0; i < nInfoCnt; i++) {
                 mLIST_VALUE[i] = new LIST_VALUE();
                 mLIST_VALUE[i].CHECK = false;
                 if (i < nInfoCnt) {
-                    mLIST_VALUE[i].ID = InfoTable.getCallHistoryInfo(i).getID();
-                    mLIST_VALUE[i].NAME = makeUnitName(InfoTable.getCallHistoryInfo(i).getName());
-                    mLIST_VALUE[i].TIME = makeUnitTimestamp(InfoTable.getCallHistoryInfo(i).getTimestamp());
-                    mLIST_VALUE[i].TYPE = makeUnitType(InfoTable.getCallHistoryInfo(i).getCallResult());
-                    mLIST_VALUE[i].REMOTE_IP = InfoTable.getCallHistoryInfo(i).getRemoteIP();
-                    mLIST_VALUE[i].NEW = InfoTable.getCallHistoryInfo(i).getChecked();
+                    mLIST_VALUE[i].ID = mInfoTable.getCallHistoryInfo(i+iListCount).getID();
+                    if (mInfoTable.getCallHistoryInfo(i).getName().equals("lobby")) {
+                        mLIST_VALUE[i].NAME =  "101동 10번 로비";
+                    }
+                    else if (mInfoTable.getCallHistoryInfo(i+iListCount).getName().equals("homedev")) {
+                        //String[] strEndIP = {"10.1.1.1", "10.1.2.1", "10.1.3.1", "10.1.3.2", "10.1.1.3", "10.1.1.2", "10.1.2.2"};
+                        mLIST_VALUE[i].NAME = makeResiType(mInfoTable.getCallHistoryInfo(i+iListCount).getSIPID());
+                    }
+
+                    mLIST_VALUE[i].TIME = makeUnitTimestamp(mInfoTable.getCallHistoryInfo(i+iListCount).getTimestamp());
+                    mLIST_VALUE[i].TYPE = makeUnitType(mInfoTable.getCallHistoryInfo(i+iListCount).getCallResult());
+                    mLIST_VALUE[i].REMOTE_IP = mInfoTable.getCallHistoryInfo(i+iListCount).getName();
+                    mLIST_VALUE[i].NEW = "";
                     nStartIndex++;
                 } else {
                     mLIST_VALUE[i].ID = "";
@@ -926,28 +1108,32 @@ public class InquiryCallHistory extends WpadScreen implements CallEventListener,
                     mLIST[i].IMG_NEW.setVisibility(View.VISIBLE);
             }
 
-            if (nInfoCnt > 0)
-                MainActivity.mCallHistoryManager.updateNewCheck(mLIST_VALUE[nInfoCnt - 1].ID, mLIST_VALUE[0].ID);
+//            if (nInfoCnt > 0)
+//                MainActivity.mCallHistoryManager.updateNewCheck(mLIST_VALUE[nInfoCnt - 1].ID, mLIST_VALUE[0].ID);
 
             strText_PageNo = nCurrentPage + "/" + nTotalPage;
             TXT_PAGE.setText(strText_PageNo);
         } catch (RuntimeException re) {
-            LogUtil.errorLogInfo("", TAG, re);
+            //LogUtil.errorLogInfo("", TAG, re);
+            re.printStackTrace();
         } catch (Exception e) {
-            Log.e(TAG, "[Exception] getHistoryFromDB()");
-            //e.printStackTrace();
-            LogUtil.errorLogInfo("", TAG, e);
+            //Log.e(TAG, "[Exception] getHistoryFromDB()");
+            e.printStackTrace();
+            //LogUtil.errorLogInfo("", TAG, e);
         }
     }
 
     private void initHistoryPageInfo() {
         try {
-            LOG("[initHistoryPageInfo");
-            nHistoryCnt = MainActivity.mCallHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_CALL);
-            LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
-            nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
-            LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
+            LOG("[initHistoryPageInfo]");
+            send_call_history_inquiry("all", "60");
+//            nHistoryCnt = MainActivity.mCallHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_CALL);
+//            LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
+//            nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+//            LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
             nCurrentPage = 1;
+
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {

+ 368 - 61
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/InquiryVisitorPictureHistory.java

@@ -11,27 +11,38 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 
+import com.artncore.WallPadDataMgr.WallpadDeviceSet;
+import com.artncore.commons.define;
+import com.artncore.wallpadimap.RetProci;
 import com.util.LogUtil;
 
+import org.apache.commons.net.ftp.FTP;
+
 import java.io.File;
 import java.util.ArrayList;
 
+import kr.co.icontrols.callengine.engine.AutoSaveVisitorPicture;
 import kr.co.icontrols.callengine.engine.CallController.CallEventListener;
 import kr.co.icontrols.callengine.engine.CallManager.CALLOWNER;
 import kr.co.icontrols.callengine.engine.CallManager.CALLSTATUS;
 import kr.co.icontrols.callengine.engine.CallManager.CALLTYPE;
+import kr.co.icontrols.hdcftp.HDCFTPManager;
 import kr.co.icontrols.wallpadcall.MainActivity;
 import kr.co.icontrols.wallpadcall.MainActivity.MAINEVENT;
 import kr.co.icontrols.wallpadcall.MainActivity.MainEventListener;
 import kr.co.icontrols.wallpadcall.R;
 import kr.co.icontrols.wallpadcall.declare.Common;
 import kr.co.icontrols.wallpadcall.declare.DataClasses.VisitorPictureHistoryInfoTable;
+import kr.co.icontrols.wallpadcall.declare.DataClasses.AllVisitorPictureHistoryInfoTable;
 import kr.co.icontrols.wallpadcall.declare.Declare;
 import kr.co.icontrols.wallpadcall.declare.Declare.DEVICENAME;
 import kr.co.icontrols.wallpadcall.declare.Declare.DeviceType;
 import kr.co.icontrols.wallpadcall.declare.Global;
 import kr.co.icontrols.wallpadcall.declare.Global.ConfigValues;
 import kr.co.icontrols.wallpadcall.declare.ID;
+import kr.co.icontrols.wallpadcall.imap.Request_start_talking;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_delete;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_inquiry;
 import kr.co.icontrols.wallpadsupport.WpadImageView;
 import kr.co.icontrols.wallpadsupport.WpadImageView.TOUCH_KIND;
 import kr.co.icontrols.wallpadsupport.WpadScreen;
@@ -128,6 +139,7 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
 
     String strText_PageNo = "1/1";
     VisitorPictureHistoryInfoTable mVisitorPictureHistoryInfoTable = new VisitorPictureHistoryInfoTable();
+    AllVisitorPictureHistoryInfoTable mAllVisitorPictureHistoryInfoTable = new AllVisitorPictureHistoryInfoTable();
 
     public InquiryVisitorPictureHistory(Context context, RelativeLayout layout) {
         super(context, layout);
@@ -225,7 +237,7 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
             BTN_DELETE_ALL = new WpadImageView(context, TOUCH_KIND.BUTTON, 230, 272, R.drawable.btn_visitor_all_del_normal, R.drawable.btn_visitor_all_del_pressed, ID.SCREEN.INQUIRYVISITORPICTUREHISTORY.ELEMENT.BUTTON.DELETE_ALL);
             ViewRegistration(layout, BTN_DELETE_ALL, Common.ImgPosition.GetX(980), Common.ImgPosition.GetY(382));
 
-            getHistoryFromDB();
+            //getHistoryFromDB();
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -268,6 +280,7 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
             ((MainActivity) mContext).finishManual(ID.MANUAL.MANUAL_ALL);
             ((MainActivity) mContext).releaseMainEventListener();
             ((MainActivity) mContext).setTopSetBtnVisible(false);
+            setDirEmpty(define.VISITOR_PICTURE_LOCATION);
 //            ((MainActivity) mContext).checkMemoryUsage(); // 메모리 체크
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -426,12 +439,13 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CONFIRM");
                     if (strItemType.equals("VisitorPictures_All")) {
                         deleteAllItems();
-                        getHistoryFromDB();
+                        initHistoryPageInfo();
+                        //getHistoryFromDB();
                     } else if (strItemType.equals("VisitorPictures")) {
                         deleteSelectedItems();
                         resetCheckBox();
                         initHistoryPageInfo();
-                        getHistoryFromDB();
+                        //getHistoryFromDB();
                     }
                 } else if (nID == ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL) {
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL");
@@ -482,25 +496,28 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
                 }
             } else if (strName.contains("Front")) {
                 strResult = "현관";
-            } else {
-                String[] strParse_01 = strName.split("/");
-                String strType = strParse_01[0];
-                String[] strParse_02 = strParse_01[1].split("-");
-                String strDong = strParse_02[0];
-                String strHo = strParse_02[1];
-
-                if (strType.equalsIgnoreCase(DEVICENAME.strType_Lobby)) {
-                    strResult = strDong + "동 " + strHo + "번 로비";
-                } else if (strType.equalsIgnoreCase(DEVICENAME.strType_Guard)) {
-                    String strRemoteIP = Global.makeIPAddress(DeviceType.GUARD, strDong, strHo);
-                    strResult = getGuardName(strRemoteIP);
-                    if (strResult.equals("NONE") || strResult.equals("ERROR")) {
-                        strResult = strDong + "동 " + strHo + "번 경비";
-                    }
-                } else {
-                    strResult = strDong + "동 " + strHo + "호";
-                }
-            }
+            } else if (strName.contains("LOBBY")) {
+                strResult = "101동 10번 로비";
+            } 
+//            } else {
+//                String[] strParse_01 = strName.split("/");
+//                String strType = strParse_01[0];
+//                String[] strParse_02 = strParse_01[1].split("-");
+//                String strDong = strParse_02[0];
+//                String strHo = strParse_02[1];
+//
+//                if (strType.equalsIgnoreCase(DEVICENAME.strType_Lobby)) {
+//                    strResult = strDong + "동 " + strHo + "번 로비";
+//                } else if (strType.equalsIgnoreCase(DEVICENAME.strType_Guard)) {
+//                    String strRemoteIP = Global.makeIPAddress(DeviceType.GUARD, strDong, strHo);
+//                    strResult = getGuardName(strRemoteIP);
+//                    if (strResult.equals("NONE") || strResult.equals("ERROR")) {
+//                        strResult = strDong + "동 " + strHo + "번 경비";
+//                    }
+//                } else {
+//                    strResult = strDong + "동 " + strHo + "호";
+//                }
+//            }
 
             if (ConfigValues.bEasyModeUse) {
                 return String.format("[%s] ", strResult);
@@ -546,21 +563,26 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
     // 방문자 사진 파일의 파일명에서 방문자 사진 시간을 구한다.
     private String makeUnitTimestampFromFile(String strTimestamp) {
         try {
-//            LOG("[makeUnitTimestampFromFile] strTimestamp [" + strTimestamp + "]");
-            String[] strParse_01 = strTimestamp.split("/");   // 파일경로명 파싱
-            strParse_01 = strParse_01[strParse_01.length - 1].split("\\.");   // 파일명을 추출하여 확장자 제거
-            strParse_01 = strParse_01[0].split("_");   // 파일명에서 시간정보 분리
-            StringBuffer strDate = new StringBuffer(strParse_01[5]);   // 날짜
-            StringBuffer strTime = new StringBuffer(strParse_01[6]);   // 시간
-//            LOG("[makeUnitTimestampFromFile] strDate [" + strDate + "], strTime [" + strTime + "]");
-            strDate.insert(6, ".");
-            strDate.insert(4, ".");
+////            LOG("[makeUnitTimestampFromFile] strTimestamp [" + strTimestamp + "]");
+//            String[] strParse_01 = strTimestamp.split("/");   // 파일경로명 파싱
+//            strParse_01 = strParse_01[strParse_01.length - 1].split("\\.");   // 파일명을 추출하여 확장자 제거
+//            strParse_01 = strParse_01[0].split("_");   // 파일명에서 시간정보 분리
+//            StringBuffer strDate = new StringBuffer(strParse_01[5]);   // 날짜
+//            StringBuffer strTime = new StringBuffer(strParse_01[6]);   // 시간
+////            LOG("[makeUnitTimestampFromFile] strDate [" + strDate + "], strTime [" + strTime + "]");
+//            strDate.insert(6, ".");
+//            strDate.insert(4, ".");
+//
+//            strTime.insert(4, ":");
+//            strTime.insert(2, ":");
+//
+//            String strResult = strDate + " " + strTime;
+//            LOG("[makeUnitTimestampFromFile] strResult = " + strResult);
+            String strResult = "";
 
-            strTime.insert(4, ":");
-            strTime.insert(2, ":");
+            String[] strSplit = strTimestamp.split("\\.");
 
-            String strResult = strDate + " " + strTime;
-            LOG("[makeUnitTimestampFromFile] strResult = " + strResult);
+            strResult = strSplit[0] + "." + strSplit[1] + "." + strSplit[2] + " " + strSplit[3] + ":" + strSplit[4] + ":" + strSplit[5];
             return strResult;
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
@@ -575,6 +597,9 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
 
     private void runPictureViewer(int nID) {
         try {
+
+            int iListCount = (nCurrentPage-1) * 6;
+            nID = nID + iListCount;
             LOG("[runPictureViewer] nID [" + nID + "]");
             Global.strVisitorPictureID = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nID).getID();
             super.setChangeScreen(ID.SCREEN.SCREEN_VISITORPICTUREVIEWER);
@@ -727,19 +752,57 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
         }
     }
 
+    private boolean send_visitor_picture_delete(String strMsg, String strCount) {
+        try {
+            LOG_INFO("[send_visitor_picture_delete] strType() "+ strMsg + " strCount " + strCount);
+            final Request_visitor_picture_delete visitor_picture_delete = new Request_visitor_picture_delete(mContext);
+            if (visitor_picture_delete.send_visitor_picture_delete(strMsg, strCount)) {
+                visitor_picture_delete.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+
+                        LOG_INFO("[send_visitor_picture_delete] ProcSuccess() ");
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_visitor_picture_delete] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_visitor_picture_delete] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_visitor_picture_delete(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
     private void deleteSelectedItems() {
         try {
-            ArrayList<String> SelectedIDs = new ArrayList<String>();
-            ArrayList<String> SelectedURIs = new ArrayList<String>();
+            int iListCount = (nCurrentPage-1) * 6;
+            int iCount = 0;
+            String strMsg = "";
             for (int i = 0; i < nActivatedListCnt; i++) {
                 if (mLIST_VALUE[i].CHECK) {
-                    SelectedIDs.add(mLIST_VALUE[i].ID);
-                    SelectedURIs.add(mLIST_VALUE[i].URI);
+                    //SelectedIDs.add(mLIST_VALUE[i].ID);
+                    //SelectedURIs.add(mLIST_VALUE[i].URI);
+                    strMsg += mAllVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i + iListCount).getData() + "\r\n";
+                    iCount++;
                 }
                 mLIST_VALUE[i].CHECK = false;
             }
-            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE, SelectedIDs);
-            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(SelectedURIs);
+            send_visitor_picture_delete(strMsg, String.valueOf(iCount));
+
+            //MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE, SelectedIDs);
+            //MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(SelectedURIs);
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -751,9 +814,10 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
 
     private void deleteAllItems() {
         try {
-            MainActivity.mVisitorPictureHistoryManager.deleteDBFile();
-            MainActivity.mVisitorPictureHistoryManager.deleteVisitorPictureDirectory();
-            MainActivity.mVisitorPictureHistoryManager.initVisitorPictureHistory(mContext);
+            send_visitor_picture_delete("", "all");
+//            MainActivity.mVisitorPictureHistoryManager.deleteDBFile();
+//            MainActivity.mVisitorPictureHistoryManager.deleteVisitorPictureDirectory();
+//            MainActivity.mVisitorPictureHistoryManager.initVisitorPictureHistory(mContext);
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -791,6 +855,237 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
         }
     }
 
+    HDCFTPManager mFTPManager;
+    String strRemoteIP = "10.0.1.1";
+
+    public class DownloadVisitorPicture extends Thread {
+
+        boolean bMainServer2dot0 = false;
+
+        public DownloadVisitorPicture() {
+            LOG_INFO("[DownloadVisitorPicture] ===== START =====");
+            WallpadDeviceSet wallpadDeviceSet = new WallpadDeviceSet(mContext);
+            try {
+                bMainServer2dot0 = wallpadDeviceSet.GetNewDanjiServer();
+                LOG_INFO("[DownloadVisitorPicture] bMainServer2dot0 [" + bMainServer2dot0 + "]");
+                wallpadDeviceSet.closeDB();
+            } catch (RuntimeException re) {
+                LogUtil.errorLogInfo("", TAG, re);
+            } catch (Exception e) {
+                Log.e(TAG, "[Exception] UploadVisitorPicture()");
+                //e.printStackTrace();
+                LogUtil.errorLogInfo("", TAG, e);
+                wallpadDeviceSet.closeDB();
+            }
+        }
+
+        public void run() {
+            try {
+                mFTPManager = new HDCFTPManager();
+                if (!mFTPManager.connectFTP(strRemoteIP)) {
+                    Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> connectFTP(...)");
+                    return;
+                }
+
+                if (!mFTPManager.loginFTP(strReply_User, strReply_PW)) {
+                    Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> loginFTP(...)");
+                    return;
+                }
+
+                if (!bMainServer2dot0) {
+                    if (!mFTPManager.setPassiveMode()) {
+                        Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> setPassiveMode(...)");
+                        disconnectFTP();
+                        return;
+                    }
+                }
+
+                if (!mFTPManager.setCtrlEncoding(mFTPManager.ENCODING_TYPE_EUC_KR)) {
+                    Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> setCtrlEncoding(...)");
+                    disconnectFTP();
+                    return;
+                }
+
+                if (!mFTPManager.setFileType(FTP.BINARY_FILE_TYPE)) {
+                    Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> setFileType(...)");
+                    disconnectFTP();
+                    return;
+                }
+
+                int iCount = mAllVisitorPictureHistoryInfoTable.getCnt();
+
+
+                for(int i = 0; i < iCount; i++)
+                {
+                    String strRemoteURI = mAllVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getPath() + "/" +
+                            mAllVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getFilename();
+                    String strLocalURI = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getURI();
+                    if (!mFTPManager.downloadFile(strRemoteURI, strLocalURI)) {
+                        Log.w(TAG, "[DownloadVisitorPicture.run()] FAIL!! -> uploadFile(...) " + i);
+                        disconnectFTP();
+                        return;
+                    }
+
+                    //
+                }
+                //
+
+
+                Thread.sleep(500);
+                disconnectFTP();
+                LOG_INFO("[DownloadVisitorPicture.run()] Complete upload!!!");
+
+            } catch (RuntimeException re) {
+                LogUtil.errorLogInfo("", TAG, re);
+            } catch (Exception e) {
+                Log.e(TAG, "[Exception] DownloadVisitorPicture.run()");
+                //e.printStackTrace();
+                LogUtil.errorLogInfo("", TAG, e);
+            }
+        }
+    }
+
+    public boolean disconnectFTP() {
+        try {
+            if (mFTPManager.logoutFTP()) {
+                if (mFTPManager.disconnectFTP()) {
+                    LOG_INFO("[disconnectFTP] disconnectFTP OK!!");
+                    return true;
+                }
+            }
+            LOG_INFO("[disconnectFTP] disconnectFTP FAIL!!");
+            return false;
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] disconnectFTP()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+
+    String strReply_User = "";
+    String strReply_PW = "";
+    String strReply_Path = "";
+
+    private boolean send_visitor_picture_inquiry(String strPage, String strCount) {
+        try {
+            LOG_INFO("[send_visitor_picture_inquiry] strPage() "+ strPage + " strCount " + strCount);
+            final Request_visitor_picture_inquiry visitor_picture_inquiry = new Request_visitor_picture_inquiry(mContext);
+            if (visitor_picture_inquiry.send_visitor_picture_inquiry("101", "101", strPage, strCount)) {
+                visitor_picture_inquiry.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        //nHistoryCnt = MainActivity.mVisitorPictureHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE);
+                        //LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
+                        //nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+                        //LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcSuccess()");
+                        visitor_picture_inquiry.SetItem("homeaddr");
+                        strReply_User = visitor_picture_inquiry.GetAttributeVal(0, "user");
+                        strReply_PW = visitor_picture_inquiry.GetAttributeVal(0, "passwd");
+
+                        visitor_picture_inquiry.SetItem("inquiry_info");
+                        nHistoryCnt = Integer.parseInt(visitor_picture_inquiry.GetAttributeVal(0, "total"));
+                        LOG("[send_visitor_picture_inquiry] nHistoryCnt = " + nHistoryCnt);
+                        nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+                        LOG("[send_visitor_picture_inquiry] nTotalPage = " + nTotalPage);
+
+                        int nQuantity = Integer.parseInt(visitor_picture_inquiry.GetAttributeVal(0, "quantity"));
+
+                        mVisitorPictureHistoryInfoTable.clearTable();
+                        mAllVisitorPictureHistoryInfoTable.clearTable();
+
+                        visitor_picture_inquiry.SetItem("visitor_pic");
+
+                        for(int i = 0; i < nQuantity; i++)
+                        {
+                            //LOG_INFO("[send_call_history_inquiry] " + i + " " + call_history_inquiry.GetAttributeVal(i, "event_time"));
+
+                            String strName = visitor_picture_inquiry.GetAttributeVal(i, "filename");
+                            String strPath = visitor_picture_inquiry.GetAttributeVal(i, "path");
+                            String strReply_Path = strPath;
+                            String strTimestamp = visitor_picture_inquiry.GetAttributeVal(i, "time");
+                            String strURI = define.VISITOR_PICTURE_LOCATION + "/" + strName;
+                            LOG_INFO("[send_call_history_inquiry] strURI " + i + " " + strURI);
+                            File VisitorDirectory = new File(define.VISITOR_PICTURE_LOCATION);
+                            if (!VisitorDirectory.exists()) {
+                                VisitorDirectory.mkdirs();
+                            }
+
+                            mVisitorPictureHistoryInfoTable.addVisitorPictureHistoryInfo(String.valueOf(i), strName, "", "", "", strURI, "", strTimestamp);
+
+                            mAllVisitorPictureHistoryInfoTable.addVisitorPictureHistoryInfo(visitor_picture_inquiry.GetAttributeVal(i, "dong"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "ho"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "time"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "path"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "filename"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "message")
+                            );
+
+                        }
+
+                        DownloadVisitorPicture mDownloadVisitorPicture = new DownloadVisitorPicture();
+                        mDownloadVisitorPicture.start();
+
+//                        visitor_picture_inquiry.SetItem("ftp_info");
+//                        strReply_User = visitor_access_info.GetAttributeVal(0, "user");
+//                        strReply_PW = visitor_access_info.GetAttributeVal(0, strPass_Key);
+//                        strReply_Path = visitor_access_info.GetAttributeVal(0, "path");
+                        //MainActivity.mCallController.mSIPInterface.requestCallForwardToStun(MainActivity.mCallController.makeCallForwarInfo(strTargetIP));
+
+                        try {
+                            Thread.sleep(1500);
+//                            Thread.sleep(500);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+
+                        getHistoryFromDB();
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_visitor_picture_inquiry(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    public void setDirEmpty(String dirName){
+        String path = dirName;
+        File dir = new File(path);
+        File[] childFileList = dir.listFiles();
+        if (dir.exists())
+        {
+            for (File childFile : childFileList)
+            {
+                if (childFile.isDirectory())
+                {
+                    setDirEmpty(childFile.getAbsolutePath()); //하위 디렉토리
+                } else {
+                    childFile.delete(); //하위 파일
+                }
+            }
+            //dir.delete();
+        }
+    }
+
     private void getHistoryFromDB() {
         try {
             LOG_DEBUG("[getHistoryFromDB] nCurrentPage = " + nCurrentPage + ", nTotalPage = " + nTotalPage);
@@ -811,9 +1106,9 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
                 nCnt = LIST_CNT - ((nStartIndex + (LIST_CNT - 1)) - nHistoryCnt);
             }
 
-            mVisitorPictureHistoryInfoTable.clearTable();
-            mVisitorPictureHistoryInfoTable = MainActivity.mVisitorPictureHistoryManager.getVisitorPictureHistory(nStartIndex - 1, nCnt);
-            if (mVisitorPictureHistoryInfoTable == null) {
+            //mVisitorPictureHistoryInfoTable.clearTable();
+            //mVisitorPictureHistoryInfoTable = MainActivity.mVisitorPictureHistoryManager.getVisitorPictureHistory(nStartIndex - 1, nCnt);
+            if (nHistoryCnt == 0) {
                 BTN_DELETE.setButtonEventOffEnable(R.drawable.btn_visitor_del_disabled);
                 BTN_DELETE_ALL.setButtonEventOffEnable(R.drawable.btn_visitor_all_del_disabled);
                 BTN_PAGE_PREV.setButtonEventOffEnable(R.drawable.btn_back_disabled);
@@ -829,28 +1124,39 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
 //                BTN_PAGE_NEXT.setButtonEventOffEnable(R.drawable.btn_next_disabled);
 //            }
 
-            int nInfoCnt = mVisitorPictureHistoryInfoTable.getCnt();
+            int nInfoCnt = 0;
+
+            int iListCount = (nCurrentPage-1) * 6;
+
+            if (nCurrentPage == nTotalPage)
+            {
+                nInfoCnt = nHistoryCnt - iListCount;
+            }
+            else
+                nInfoCnt = 6;
+
             nActivatedListCnt = nInfoCnt;
             LOG_DEBUG("[getHistoryFromDB] nInfoCnt = " + nInfoCnt);
+            
             for (int i = 0; i < nInfoCnt; i++) {
                 mLIST_VALUE[i] = new LIST_VALUE();
                 mLIST_VALUE[i].CHECK = false;
                 if (i < nInfoCnt) {
-                    mLIST_VALUE[i].ID = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getID();
+                    mLIST_VALUE[i].ID = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getID();
                     // 방문자 사진의 시간은 DB 추출방식에서 File 추출방식으로 변경한다. (JEFF, 2021.05.15)
                     // 기존: 방문자 내역 DB에 저장된 Timestamp를 표시 -> 실제 사진 저장시간과 상이하여, 파일의 저장시간을 이용하는 모바일 연동간에 시차가 발생한다.
                     // 개선: 방문자 사진 파일명에 명기된 파일저장시간을 추출하여 표시 -> 월패드와 모바일에 조회시 모두 동일한 시간으로 조회된다.
                     if (ConfigValues.bEasyModeUse) {
-                        mLIST_VALUE[i].INFO = makeUnitName(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getName()) + "\n"
-                                + makeUnitTimestampFromFile(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getURI());
+                        mLIST_VALUE[i].INFO = makeUnitName(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getName()) + "\n"
+                                + makeUnitTimestampFromFile(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getTimestamp());
                     }
                     else {
-                        mLIST_VALUE[i].INFO = makeUnitName(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getName())
-                                + makeUnitTimestampFromFile(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getURI());
+                        mLIST_VALUE[i].INFO = makeUnitName(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getName())
+                                + makeUnitTimestampFromFile(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getTimestamp());
                     }
-                    mLIST_VALUE[i].URI = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getURI();
-                    mLIST_VALUE[i].NEW = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getChecked();
-                    mLIST_VALUE[i].THIEF = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getThief();
+                    mLIST_VALUE[i].URI = mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i+iListCount).getURI();
+                    mLIST_VALUE[i].NEW = "";
+                    mLIST_VALUE[i].THIEF = "";
                     nStartIndex++;
                 } else {
                     mLIST_VALUE[i].ID = "";
@@ -872,7 +1178,7 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
                 drawVisitorPicture(i, mLIST_VALUE[i].URI);
             }
 
-            if (nInfoCnt > 0) MainActivity.mVisitorPictureHistoryManager.updateNewCheck(mLIST_VALUE[nInfoCnt - 1].ID, mLIST_VALUE[0].ID);
+            //if (nInfoCnt > 0) MainActivity.mVisitorPictureHistoryManager.updateNewCheck(mLIST_VALUE[nInfoCnt - 1].ID, mLIST_VALUE[0].ID);
             showCheckBox(false);
             strText_PageNo = nCurrentPage + "/" + nTotalPage;
             TXT_PAGE.setText(strText_PageNo);
@@ -888,11 +1194,12 @@ public class InquiryVisitorPictureHistory extends WpadScreen implements CallEven
     private void initHistoryPageInfo() {
         try {
             LOG("[initHistoryPageInfo]");
-            nHistoryCnt = MainActivity.mVisitorPictureHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE);
-            LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
-            nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
-            LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
+            //nHistoryCnt = MainActivity.mVisitorPictureHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE);
+            //LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
+            //nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+            //LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
             nCurrentPage = 1;
+            send_visitor_picture_inquiry("1", "60");
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {

File diff suppressed because it is too large
+ 324 - 374
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkFront.java


+ 164 - 8
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkLobby.java

@@ -53,7 +53,10 @@ import kr.co.icontrols.wallpadcall.declare.Global.ConfigValues;
 import kr.co.icontrols.wallpadcall.declare.Global.DOORLOCKTYPE;
 import kr.co.icontrols.wallpadcall.declare.ID;
 import kr.co.icontrols.wallpadcall.imap.Request_check_sip_activation;
+import kr.co.icontrols.wallpadcall.imap.Request_lobby_capture;
 import kr.co.icontrols.wallpadcall.imap.Request_lobby_open;
+import kr.co.icontrols.wallpadcall.imap.Request_start_talking;
+import kr.co.icontrols.wallpadcall.imap.Request_stop_talking;
 import kr.co.icontrols.wallpadsupport.WpadImageView;
 import kr.co.icontrols.wallpadsupport.WpadImageView.TOUCH_KIND;
 import kr.co.icontrols.wallpadsupport.WpadScale;
@@ -268,6 +271,9 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
 //            bEnableVisitorPic = false;   // 부재중 방문객 사진 저장은 임시로 삭제한다.
 
             MainActivity.mIOInterface.ctrlPopupGUI(false);
+            MainActivity.mCallController.mSIPInterface.videoSet(true, false, true);
+
+            sendHandlerMsgDelayed(HANDLERMSG.ENABLE_SAVE_VISITORPICTURE, 0, 0, null, 3000);
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -297,6 +303,7 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
         super.onClose();
         try {
             LOG_INFO("[onClose]");
+            MainActivity.mIOInterface.ctrlPopupGUI(true);
             if (MainActivity.mIOInterface != null) MainActivity.mIOInterface.ctrlWallPadLED_Call(false);
             nSelectedFilter = 0;
             sendReliefFilterSelectBR(nSelectedFilter);
@@ -360,15 +367,21 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
                     } else if (nID == ID.SCREEN.TALKLOBBY.ELEMENT.BUTTON.END) {
                         bEnableVisitorPic = false;
                         doEnd();
+                        send_stop_talking_request(RemoteIDInfo.strIP);
                     } else if (nID == ID.SCREEN.TALKLOBBY.ELEMENT.BUTTON.SAVE_PICTURE) {
-                        String strVisitorPicResult = MainActivity.mCallController.saveVisitorPicture(CALLTYPE.LOBBY, MainActivity.mCallController.mCallInfo.getLOBBY(), RemoteIDInfo.strSIPID, true, false, false);
-                        LOG_INFO("[onTouchEvent] strVisitorPicResult [" + strVisitorPicResult + "]");
+                        //String strVisitorPicResult = MainActivity.mCallController.saveVisitorPicture(CALLTYPE.LOBBY, MainActivity.mCallController.mCallInfo.getLOBBY(), RemoteIDInfo.strSIPID, true, false, false);
+                        //LOG_INFO("[onTouchEvent] strVisitorPicResult [" + strVisitorPicResult + "]");
+
+                        send_lobby_capture_request(RemoteIDInfo.strIP);
+
                         enableSavePicBTN(false);
                         sendHandlerMsgDelayed(HANDLERMSG.ENABLE_SAVE_VISITORPICTURE, 0, 0, null, 3000);
                     } else if (nID == ID.SCREEN.TALKLOBBY.ELEMENT.BUTTON.DOOROPEN) {
                         if (!bSentiMAP) {
                             sendHandlerMsg(HANDLERMSG.HIDE_LOBBYVIDEO, 0, 0, null); // 문열림으로 통화 종료시 로비 영상 노이즈가 생기므로 영상을 GUI 아래로 내림
                             doDoorOpen();
+                            //doEnd();
+                            //send_stop_talking_request(RemoteIDInfo.strIP);
                         }
                     } else if (ID.SCREEN.TALKLOBBY.ELEMENT.BUTTON.RELIEF_FILTER_01 <= nID && nID <= ID.SCREEN.TALKLOBBY.ELEMENT.BUTTON.RELIEF_FILTER_04) {
                         LOG_INFO("[onTouchEvent] [RELIEF_FILTER] BUTTON");
@@ -505,7 +518,7 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
                 else if (eCallStatus == CALLSTATUS.END) {
                     bEnableVisitorPic = false;
                     bReliefCallInit = false;
-                    Global.stopMelodyRepeat();
+                    //Global.stopMelodyRepeat();
                     MainActivity.mCallController.setTalkPath(CALLPATH.NORMAL);
                     ((MainActivity) mContext).finishPopUp(ID.POPUP.POPUP_ALL);
                     ((MainActivity) mContext).finishManual(ID.MANUAL.MANUAL_ALL);
@@ -953,9 +966,10 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
 
     private void doTalk(CALLOWNER eCallOwner) {
         try {
-            LOG_INFO("[doTalk] eCallOwner [" + eCallOwner + "], nSelectedFilter [" + nSelectedFilter + "]");
+            LOG_INFO("[doTalk] eCallOwner [" + eCallOwner + "], nSelectedFilter [" + nSelectedFilter + "]" + "RemoteIDInfo.strIP [" + RemoteIDInfo.strIP + "]");
             if (MainActivity.mCallController.mCallInfo.getLOBBY() == CALLSTATUS.CALLED) {
-                MainActivity.mCallController.acceptMoIPCall(false);
+                send_start_talking_request(RemoteIDInfo.strIP);
+               //MainActivity.mCallController.acceptMoIPCall(false);
                 MainActivity.mCallController.mCallInfo.setCallOwner(eCallOwner);
             } else {
                 LOG_INFO("[doTalk] Invalid CALLSTATUS [" + MainActivity.mCallController.mCallInfo.getLOBBY() + "]");
@@ -974,10 +988,28 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
             if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                 LOG_INFO("[doEnd] CALLSTATUS [" + MainActivity.mCallController.mCallInfo.getLOBBY() + "]");
                 sendHandlerMsg(HANDLERMSG.HIDE_LOBBYVIDEO, 0, 0, null); // 통화 종료시 로비 영상 노이즈가 생기므로 영상을 GUI 아래로 내림
+
                 if (MainActivity.mCallController.mCallInfo.getLOBBY() == CALLSTATUS.CALLED) {
                     Global.change1stCallLogAction(CALLACTION.REJECT);
+                    //Global.stopMelodyRepeat();
+                    //MainActivity.mCallController.rejectMoIPCall();
+
+                    bEnableVisitorPic = false;
+                    bReliefCallInit = false;
                     Global.stopMelodyRepeat();
-                    MainActivity.mCallController.rejectMoIPCall();
+                    MainActivity.mCallController.setTalkPath(CALLPATH.NORMAL);
+                    ((MainActivity) mContext).displayRemoteID(null);
+                    //MainActivity.mSound.PlayMent(SND.setting.RETRY_ACTION);
+                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.LOBBY, CALLSTATUS.IDLE);
+                    MainActivity.mCallController.stop1stCallTimer();
+                    MainActivity.mCallController.stop2ndCallTimer();
+                    ((MainActivity) mContext).finishPopUp(ID.POPUP.POPUP_NOTICE_SUBPHONETALK);
+                    Global.change1stCallLogAction(CALLACTION.REJECT);
+                    Global.add1stCallHistoryInfoFinal();
+                    nSelectedFilter = 0;
+                    sendReliefFilterSelectBR(nSelectedFilter);
+                    MainActivity.mCallController.MultiCallScenarioManager();
+                    //send_stop_talking_request(RemoteIDInfo.strIP);
                 }
                 else if (MainActivity.mCallController.mCallInfo.getLOBBY() == CALLSTATUS.TALKING) {
                     if (MainActivity.mCallController.mCallInfo.getCallOwner() == CALLOWNER.MOBILE)
@@ -1033,6 +1065,7 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
                 Global.change1stCallLogAction(CALLACTION.DOOR);
             } else if (MainActivity.mCallController.mCallInfo.getLOBBY() == CALLSTATUS.TALKING) {
 //                Global.changeVolumeMoIPMode(CALLTYPE.NONE);
+                Global.stopMelodyRepeat();
                 if (!send_lobby_open_request(RemoteIDInfo.strIP)) {
                     MainActivity.mSound.Play(SND.setting.RETRY_ACTION);
                 }
@@ -1439,7 +1472,7 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
 //                        if (MainActivity.mCallController.getTalkPath() == CALLPATH.NORMAL) {
 //                            MainActivity.mIOInterface.setMICGain(0);   // 월패드에 출력되는 문열림 멘트가 월패드 마이크를 통해 로비폰에 전달되므로, 멘트 출력전에 Micgain을 0으로 설정한다.
 //                        }
-                        MainActivity.mCallController.setTalkPath(CALLPATH.NORMAL);
+                        //MainActivity.mCallController.setTalkPath(CALLPATH.NORMAL);
 //                        MainActivity.mSound.Play(SND.mode.OPENDOOR);
                         mPathCheckHandler.sendEmptyMessage(2); // 통화패스 Normal로 변경 확인 후 멘트 출력 seulki
 
@@ -1457,6 +1490,7 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
 //                            BTN_RELIEF_FILTER_03.setButtonEventOffEnable(R.drawable.btn_filter_3_normal);
 //                            BTN_RELIEF_FILTER_04.setButtonEventOffEnable(R.drawable.btn_filter_4_normal);
                         }
+                        doEnd();
                     }
 
                     @Override
@@ -1485,6 +1519,44 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
         return false;
     }
 
+    private boolean send_lobby_capture_request(String strTargetIP) {
+        LOG_INFO("[send_lobby_capture_request] strTargetIP [" + strTargetIP + "]");
+
+        try {
+            Request_lobby_capture lobby_capture = new Request_lobby_capture(mContext);
+            if (lobby_capture.send_lobby_capture(strTargetIP, null)) {
+                lobby_capture.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        LOG_INFO("[send_lobby_capture_request] ProcSuccess()");
+
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_lobby_capture_request] ProcError()");
+
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_lobby_capture_request] ProcDoing()");
+
+                    }
+                });
+                return true;
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_lobby_capture_request(String strTargetIP, String strMessage)");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+        return false;
+    }
+
     // 방문자 사진 자동 저장
     boolean bEnableVisitorPic = false;
 
@@ -1551,6 +1623,81 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
         }
     }
 
+    private boolean send_stop_talking_request(String strTargetIP) {
+        try {
+            LOG_INFO("[send_stop_talking_request] strTargetIP() " + strTargetIP);
+            //Request_start_talking request_start_talking = new Request_start_talking(mContext);
+            Request_stop_talking request_stop_talking = new Request_stop_talking(mContext);
+            if (request_stop_talking.send_stop_talking(strTargetIP, null)) {
+                request_stop_talking.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        LOG_INFO("[send_stop_talking_request] ProcSuccess()");
+                        //MainActivity.mCallController.mSIPInterface.requestCallForwardToStun(MainActivity.mCallController.makeCallForwarInfo(strTargetIP));
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_stop_talking_request] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_stop_talking_request] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_check_sip_activation_request(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+            MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+        }
+        return false;
+
+
+    }
+
+
+    private boolean send_start_talking_request(String strTargetIP) {
+        try {
+            LOG_INFO("[send_start_talking_request] strTargetIP() "+ strTargetIP);
+            Request_start_talking request_start_talking = new Request_start_talking(mContext);
+            if (request_start_talking.send_start_talking(strTargetIP, null)) {
+                request_start_talking.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        LOG_INFO("[send_start_talking_request] ProcSuccess()");
+                        //MainActivity.mCallController.mSIPInterface.requestCallForwardToStun(MainActivity.mCallController.makeCallForwarInfo(strTargetIP));
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_start_talking_request] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_start_talking_request] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_check_sip_activation_request(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+            MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+        }
+        return false;
+
+
+    }
+
     private boolean send_check_sip_activation_request(final String strTargetIP) {
         try {
             Request_check_sip_activation check_sip_activation = new Request_check_sip_activation(mContext);
@@ -2109,7 +2256,14 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
                 }
             }
             else if (msg.what == 3) {
-                Log.d(TAG, "[mPathCheckHandler.handleMessage] Handler finish!! PATH [NORMAL] -> play dooropen ment!");
+                Log.d(TAG, "[stopMelodyRepeat.handleMessage] Handler finish!! PATH [NORMAL] -> play dooropen ment!");
+                try {
+
+                    Thread.sleep(3000);
+                } catch (InterruptedException e) {
+                    //e.printStackTrace();
+                    LogUtil.errorLogInfo("", TAG, e);
+                }
                 int nMentDuration = MainActivity.mSound.PlayMent(SND.mode.OPENDOOR);
                 try {
                     Log.d(TAG, "[mPathCheckHandler.handleMessage] nMentDuration -> " + nMentDuration);
@@ -2126,8 +2280,10 @@ public class TalkLobby extends WpadScreen implements CallEventListener, MainEven
     private void finishWallpadCallApp() {
         try {
             doEnd();
+            //send_stop_talking_request(RemoteIDInfo.strIP);
             if (MainActivity.mCallController.mCallInfo.getPSTNCallHold()) return;
             ((MainActivity) mContext).finishWallPadCall();
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {

+ 435 - 117
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/TalkResidence.java

@@ -24,6 +24,8 @@ import com.util.LogUtil;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import kr.co.icontrols.callengine.engine.CallController.CallEventListener;
 import kr.co.icontrols.callengine.engine.CallManager.CALLEVENTTYPE;
@@ -51,7 +53,9 @@ import kr.co.icontrols.wallpadcall.declare.Global.CALLDIRECTION;
 import kr.co.icontrols.wallpadcall.declare.Global.CALLRESULT;
 import kr.co.icontrols.wallpadcall.declare.Global.ConfigValues;
 import kr.co.icontrols.wallpadcall.declare.ID;
+import kr.co.icontrols.wallpadcall.imap.Request_call_history_save;
 import kr.co.icontrols.wallpadcall.imap.Request_check_sip_activation;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_delete;
 import kr.co.icontrols.wallpadsupport.Version;
 import kr.co.icontrols.wallpadsupport.WpadImageView;
 import kr.co.icontrols.wallpadsupport.WpadImageView.TOUCH_KIND;
@@ -100,21 +104,23 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
     WpadImageView BTN_PORTRAIT;
     WpadImageView BTN_DELETE;
     WpadImageView BTN_DIVISION;
-    WpadImageView[] BTN_TENKEY = new WpadImageView[12];
+    WpadImageView[] BTN_TENKEY = new WpadImageView[6];
     int[][] TENKEYS = {
-            {R.drawable.btn_num_1_normal, R.drawable.btn_num_1_pressed},
-            {R.drawable.btn_num_2_normal, R.drawable.btn_num_2_pressed},
-            {R.drawable.btn_num_3_normal, R.drawable.btn_num_3_pressed},
-            {R.drawable.btn_num_4_normal, R.drawable.btn_num_4_pressed},
-            {R.drawable.btn_num_5_normal, R.drawable.btn_num_5_pressed},
-            {R.drawable.btn_num_6_normal, R.drawable.btn_num_6_pressed},
-            {R.drawable.btn_num_7_normal, R.drawable.btn_num_7_pressed},
-            {R.drawable.btn_num_8_normal, R.drawable.btn_num_8_pressed},
-            {R.drawable.btn_num_9_normal, R.drawable.btn_num_9_pressed},
-            {R.drawable.btn_num_dong_normal, R.drawable.btn_num_dong_pressed},
-            {R.drawable.btn_num_0_normal, R.drawable.btn_num_0_pressed},
-            {R.drawable.btn_num_ho_normal, R.drawable.btn_num_ho_pressed}
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_pressed, R.drawable.btn_floor_1_selected}, //10.1.1.1
+            {R.drawable.btn_floor_2_normal, R.drawable.btn_floor_2_pressed, R.drawable.btn_floor_2_selected}, //10.1.2.1
+            {R.drawable.btn_floor_3_normal, R.drawable.btn_floor_3_pressed, R.drawable.btn_floor_3_selected}, //10.1.3.1
+            {R.drawable.btn_main_room_normal, R.drawable.btn_main_room_pressed, R.drawable.btn_main_room_selected}, //10.1.3.2
+            {R.drawable.btn_driver_normal, R.drawable.btn_driver_pressed, R.drawable.btn_driver_selected}, //10.1.1.3
+            {R.drawable.btn_maid_normal, R.drawable.btn_maid_pressed, R.drawable.btn_maid_selected}, //10.1.1.2
+            {R.drawable.btn_kitchen_normal, R.drawable.btn_kitchen_pressed, R.drawable.btn_kitchen_selected}, //10.1.2.2
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal},
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal},
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal},
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal},
+            {R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal, R.drawable.btn_floor_1_normal}
     };
+
+    String[] strEndIP = {"10.1.1.1", "10.1.2.1", "10.1.3.1", "10.1.3.2", "10.1.1.3", "10.1.1.2", "10.1.2.2"};
     WpadTextView TXT_RESIDENCEINFO;   // 세대정보
     WpadTextView TXT_INSTRUCTION;   // 안내문구
 
@@ -124,6 +130,9 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
     SeekBar SEEKBAR_VOLUME;
     WpadTextView TXT_VOLUME_LEVEL;
 
+    int m_nIDCnt_type = 0;
+    boolean m_bCallStateThreadStop = true;
+
     class TextResources {
         static final String strDong = "동";
         static final String strHo = "호";
@@ -144,6 +153,8 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
     int MINLENGTH_HO = 3;
     int KEYBALANCE = ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_01 - 1;
 
+
+
     int nCurrentVolume = 0;
 
     boolean bshowMyVideo = false;
@@ -162,21 +173,22 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
 
             IMG_RESIDENCE_BACKGROUND = new WpadImageView(context, TOUCH_KIND.NONE, 724, 544, R.drawable.bg_residence, 0, ID.SCREEN.TALKRESIDENCE.ELEMENT.IMAGE.BACKGROUND);
             ViewRegistration(layout, IMG_RESIDENCE_BACKGROUND, Common.ImgPosition.GetX(142), Common.ImgPosition.GetY(110));
+            IMG_RESIDENCE_BACKGROUND.setVisibility(View.INVISIBLE);
 
             IMG_VIDEO_MODULE = new WpadImageView(context, TOUCH_KIND.NONE, 720, 540, R.drawable.image_neig, 0, ID.SCREEN.TALKRESIDENCE.ELEMENT.IMAGE.VIDEO_MODULE);
             ViewRegistration(layout, IMG_VIDEO_MODULE, Common.ImgPosition.GetX(144), Common.ImgPosition.GetY(112));
-
+            IMG_VIDEO_MODULE.setVisibility(View.INVISIBLE);
             IMG_VOLUME = new WpadImageView(context, TOUCH_KIND.NONE, 40, 40, R.drawable.bar_icon_sound, 0, ID.SCREEN.TALKRESIDENCE.ELEMENT.IMAGE.VOLUME);
-            ViewRegistration(layout, IMG_VOLUME, Common.ImgPosition.GetX(454), Common.ImgPosition.GetY(707));
+            ViewRegistration(layout, IMG_VOLUME, Common.ImgPosition.GetX(318), Common.ImgPosition.GetY(707));
 
             TXT_VOLUME_LEVEL = new WpadTextView(context, false, 40, 40, Gravity.CENTER, Color.WHITE, Common.fontsize._30, false, ID.SCREEN.TALKFRONT.ELEMENT.TEXT.VOLUME_LEVEL);
-            ViewRegistration(layout, TXT_VOLUME_LEVEL, Common.ImgPosition.GetX(785), Common.ImgPosition.GetY(705));
+            ViewRegistration(layout, TXT_VOLUME_LEVEL, Common.ImgPosition.GetX(644), Common.ImgPosition.GetY(705));
 
             if (WpadScale.getWidthPixels() == WpadScale.DEFAULT_WIDTH_PIXELS) {
                 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                 LinearLayout volumeLayout = (LinearLayout) inflater.inflate(R.layout.volume_seekbar_1280, null);
                 LayoutParams volumeParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-                int volMarginLeft = WpadScale.getWidth(Common.ImgPosition.GetX(507));
+                int volMarginLeft = WpadScale.getWidth(Common.ImgPosition.GetX(359));
                 int volMarginTop = WpadScale.getHeight(Common.ImgPosition.GetY(707));
                 volumeParams.setMargins(volMarginLeft, volMarginTop, 0, 0);
                 volumeLayout.setLayoutParams(volumeParams);
@@ -189,7 +201,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                 LinearLayout volumeLayout = (LinearLayout) inflater.inflate(R.layout.volume_seekbar, null);
                 LayoutParams volumeParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-                int volMarginLeft = WpadScale.getWidth(Common.ImgPosition.GetX(502));
+                int volMarginLeft = WpadScale.getWidth(Common.ImgPosition.GetX(366));
                 int volMarginTop = WpadScale.getHeight(Common.ImgPosition.GetY(703));
                 volumeParams.setMargins(volMarginLeft, volMarginTop, 0, 0);
                 volumeLayout.setLayoutParams(volumeParams);
@@ -199,18 +211,36 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                 layout.addView(volumeLayout);
             }
 
-            int nTenKeyGuide_X = Common.ImgPosition.GetX(460);
-            int nTenKeyGuide_Y = Common.ImgPosition.GetY(112);
+            int nTenKeyGuide_X = Common.ImgPosition.GetX(142);
+            int nTenKeyGuide_Y = Common.ImgPosition.GetY(148);
             int nIDCnt = 0;
-            for (int i = 0; i < 4; i++) {
+
+            //String[] strEndIP = {"10.1.1.1", "10.1.1.2", "10.1.1.3", "10.1.1.4", "10.1.1.5", "10.1.1.6", "10.1.1.7"};
+
+
+            int nIDCnt_img = -1;
+            for(int i = 0; i < strEndIP.length; i++)
+            {
+                if (ConfigValues.strDeviceIPaddress.equals(strEndIP[i])) {
+                    m_nIDCnt_type = i;
+                    break;
+                }
+            }
+
+            for (int i = 0; i < 2; i++) {
                 for (int j = 0; j < 3; j++) {
-                    BTN_TENKEY[nIDCnt] = new WpadImageView(context, TOUCH_KIND.BUTTON, 132, 132, TENKEYS[nIDCnt][0], TENKEYS[nIDCnt][1], ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_01 + nIDCnt);
+                    if(m_nIDCnt_type == nIDCnt)
+                        nIDCnt_img +=2;
+                    else
+                        nIDCnt_img++;
+                    BTN_TENKEY[nIDCnt] = new WpadImageView(context, TOUCH_KIND.BUTTON, 236, 230, TENKEYS[nIDCnt_img][0], TENKEYS[nIDCnt_img][1], ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_01 + nIDCnt_img);
                     ViewRegistration(layout, BTN_TENKEY[nIDCnt], nTenKeyGuide_X, nTenKeyGuide_Y);
-                    nTenKeyGuide_X += 136;
+
+                    nTenKeyGuide_X += 244;
                     nIDCnt++;
                 }
-                nTenKeyGuide_X = Common.ImgPosition.GetX(460);
-                nTenKeyGuide_Y += 136;
+                nTenKeyGuide_X = Common.ImgPosition.GetX(142);
+                nTenKeyGuide_Y += 238;
             }
 
             LOG("[TalkResidence] bWallPadCameraEnable [" + ConfigValues.bWallPadCameraEnable + "]");
@@ -236,25 +266,27 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             }
 
             // 부분 임대세대 적용여부 판단
-            if (ConfigValues.bEnableHouseDivision) {
-                Log.d(TAG, "[TalkResidenceScreen] bEnableHouseDivision TRUE 분리세대");
-                BTN_DELETE = new WpadImageView(context, TOUCH_KIND.BUTTON_LC, 154, 132, R.drawable.btn_num_del_normal2, R.drawable.btn_num_del_pressed2, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DELETE);
-                ViewRegistration(layout, BTN_DELETE, Common.ImgPosition.GetX(144), Common.ImgPosition.GetY(520));
-
-                BTN_DIVISION = new WpadImageView(context, TOUCH_KIND.BUTTON, 154, 132, R.drawable.btn_num_separation_normal, R.drawable.btn_num_separation_pressed, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DIVISION);
-                ViewRegistration(layout, BTN_DIVISION, Common.ImgPosition.GetX(302), Common.ImgPosition.GetY(520));
-            } else {
-                BTN_DELETE = new WpadImageView(context, TOUCH_KIND.BUTTON_LC, 312, 132, R.drawable.btn_num_del_normal, R.drawable.btn_num_del_pressed, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DELETE);
-                ViewRegistration(layout, BTN_DELETE, Common.ImgPosition.GetX(144), Common.ImgPosition.GetY(520));
-            }
-
+//            if (ConfigValues.bEnableHouseDivision) {
+//                Log.d(TAG, "[TalkResidenceScreen] bEnableHouseDivision TRUE 분리세대");
+//                BTN_DELETE = new WpadImageView(context, TOUCH_KIND.BUTTON_LC, 154, 132, R.drawable.btn_num_del_normal2, R.drawable.btn_num_del_pressed2, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DELETE);
+//                ViewRegistration(layout, BTN_DELETE, Common.ImgPosition.GetX(144), Common.ImgPosition.GetY(520));
+//
+//                BTN_DIVISION = new WpadImageView(context, TOUCH_KIND.BUTTON, 154, 132, R.drawable.btn_num_separation_normal, R.drawable.btn_num_separation_pressed, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DIVISION);
+//                ViewRegistration(layout, BTN_DIVISION, Common.ImgPosition.GetX(302), Common.ImgPosition.GetY(520));
+//            } else {
+//                BTN_DELETE = new WpadImageView(context, TOUCH_KIND.BUTTON_LC, 312, 132, R.drawable.btn_num_del_normal, R.drawable.btn_num_del_pressed, ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.DELETE);
+//                ViewRegistration(layout, BTN_DELETE, Common.ImgPosition.GetX(144), Common.ImgPosition.GetY(520));
+//            }
+//
             TXT_RESIDENCEINFO = new WpadTextView(context, false, 292, 284, Gravity.LEFT, context.getResources().getColor(R.color.orange), Common.fontsize._46, false, ID.SCREEN.TALKRESIDENCE.ELEMENT.TEXT.RESIDENCEINFO);
             ViewRegistration(layout, TXT_RESIDENCEINFO, Common.ImgPosition.GetX(155), Common.ImgPosition.GetY(111));
             TXT_RESIDENCEINFO.setText(strTXT_RESIDENCEINFO);
+            //TXT_RESIDENCEINFO.setVisibility(View.GONE);
 
             TXT_INSTRUCTION = new WpadTextView(context, false, 317, 364, Gravity.CENTER, context.getResources().getColor(R.color.orange), Common.fontsize._52, true, ID.SCREEN.TALKRESIDENCE.ELEMENT.TEXT.INSTRUCTION);
             ViewRegistration(layout, TXT_INSTRUCTION, Common.ImgPosition.GetX(142), Common.ImgPosition.GetY(255));
             TXT_INSTRUCTION.setText(strTXT_INSTRUCTION);
+            //TXT_INSTRUCTION.setVisibility(View.GONE);
 
             displayScreenValues();
             sendHandlerMsg(HANDLERMSG.PROC_ADDCALL, 0, 0);
@@ -289,7 +321,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             if (MainActivity.bFFMPEGEnable) ((MainActivity)mContext).showRemoteVideo(false, false);
 
             MainActivity.mCallController.mVideoJNI.setDecoderInfo_V40(116, 85, 576, 405); // 세대통화시 영상 좌표 재설정
-            MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 세대통화 시작시 초기화
+            //MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 세대통화 시작시 초기화
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -324,6 +356,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                 mPathCheckHandler.removeMessages(0);
                 mPathCheckHandler.removeMessages(1);
             }
+            mbCallState = false;
             initCallVariables();
             MainActivity.mCallController.mSIPInterface.videoSet(false, false, false);
             MainActivity.mCallController.selectVideoSourceToSubPhone(CALLTYPE.NONE, true);
@@ -436,19 +469,25 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     }
                     else if (ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_01 <= nID && nID <= ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_09) {
                         int nPressedNum = nID - KEYBALANCE;
-                        if (Global.TargetInputStep == TARGETINFOINPUTSTEP.DONG) {
-                            RemoteIDInfo.strDong += nPressedNum;
-                            if (RemoteIDInfo.strDong.length() > MAXLENGTH_DONG) {
-                                RemoteIDInfo.strDong = RemoteIDInfo.strDong.substring(1, 5);
-                            }
-                            playTenkeyNo(nID);
-                        } else if (Global.TargetInputStep == TARGETINFOINPUTSTEP.HO) {
-                            RemoteIDInfo.strHo += nPressedNum;
-                            if (RemoteIDInfo.strHo.length() > MAXLENGTH_HO) {
-                                RemoteIDInfo.strHo = RemoteIDInfo.strHo.substring(1, 5);
-                            }
-                            playTenkeyNo(nID);
-                        }
+                        Global.TargetInputStep = TARGETINFOINPUTSTEP.DONG;
+
+                        playTenkeyNo(nID);
+                        Global.TargetInputStep = TARGETINFOINPUTSTEP.DONE;
+
+
+//                        if (Global.TargetInputStep == TARGETINFOINPUTSTEP.DONG) {
+//                            RemoteIDInfo.strDong += nPressedNum;
+//                            if (RemoteIDInfo.strDong.length() > MAXLENGTH_DONG) {
+//                                RemoteIDInfo.strDong = RemoteIDInfo.strDong.substring(1, 5);
+//                            }
+//                            playTenkeyNo(nID);
+//                        } else if (Global.TargetInputStep == TARGETINFOINPUTSTEP.HO) {
+//                            RemoteIDInfo.strHo += nPressedNum;
+//                            if (RemoteIDInfo.strHo.length() > MAXLENGTH_HO) {
+//                                RemoteIDInfo.strHo = RemoteIDInfo.strHo.substring(1, 5);
+//                            }
+//                            playTenkeyNo(nID);
+//                        }
                         updateResidenceInfo();
                     } else if (nID == ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_00) {
                         int nPressedNum = 0;
@@ -554,6 +593,41 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
         super.onKeyDown(keyCode, event);
     }
 
+    private boolean send_call_history_save(String strType, String strTime) {
+        try {
+            LOG_INFO("[send_call_history_save] strType() "+ strType + " strTime " + strTime);
+            final Request_call_history_save call_history_save = new Request_call_history_save(mContext);
+            if (call_history_save.send_call_history_save(RemoteIDInfo.strDong, RemoteIDInfo.strHo, strType, strTime)) {
+                call_history_save.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+
+                        LOG_INFO("[send_call_history_save] ProcSuccess() ");
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_call_history_save] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_call_history_save] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_call_history_save(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    boolean mbCallState = false;
+
     @Override
     public void onCallEvent(CALLOWNER eCallOwner, CALLSTATUS eCallStatus, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
         try {
@@ -564,6 +638,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                 MainActivity.mCallController.setRemoteInfo(strRemoteSIPID, strRemoteIP);
                 setBTNStatus();
                 if (eCallStatus == CALLSTATUS.CALLING) {
+                    mbCallState = true;
                     bRcvEnd = false;
                     Global.playMelodyRepeat(eCallType);
                     super.setFinishTimerDestroy();
@@ -573,6 +648,20 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     MainActivity.mCallController.set1stCallTimer(eCallType, MainActivity.mCallController.mCTT.CALLING);
                     updateInstruction();
                     Global.make1stCallHistoryInfo(strRemoteIP, strRemoteSIPID, CALLDIRECTION.OUT, CALLACTION.MISS, CALLRESULT.OUT_MISS);
+
+//                    String[] strEndIP = {"10.1.1.1", "10.1.1.2", "10.1.1.3", "10.1.1.4", "10.1.1.5", "10.1.1.6", "10.1.1.7"};
+//
+//                    for(int i = 0; i < strEndIP.length; i++)
+//                    {
+//                        if (strRemoteIP.equals(strEndIP[i])) {
+//
+//                            CallStateThread nr = new CallStateThread(i) ;
+//                            Thread t = new Thread(nr) ;
+//                            t.start() ;
+//                            break;
+//                        }
+//                    }
+
                 } else if (eCallStatus == CALLSTATUS.CALLED) {
                     bRcvEnd = false;
                     Global.playMelodyRepeat(eCallType);
@@ -584,6 +673,19 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     MainActivity.mCallController.set1stCallTimer(eCallType, MainActivity.mCallController.mCTT.CALLED);
                     updateScreen();
                     Global.make1stCallHistoryInfo(strRemoteIP, strRemoteSIPID, CALLDIRECTION.IN, CALLACTION.MISS, CALLRESULT.IN_MISS);
+
+
+
+                    for(int i = 0; i < strEndIP.length; i++)
+                    {
+                        if (strRemoteIP.equals(strEndIP[i])) {
+
+                            CallStateThread nr = new CallStateThread(i) ;
+                            Thread t = new Thread(nr) ;
+                            t.start() ;
+                            break;
+                        }
+                    }
                 }
                 else if (eCallStatus == CALLSTATUS.TALKING) {
                     Global.stopMelodyRepeat();
@@ -608,6 +710,24 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     updateInstruction();
                     Global.change1stCallLogAction(CALLACTION.TALK);
                     Global.add1stCallHistoryInfoFinal();
+                    if(mbCallState)
+                    {
+                        String strTimeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
+                        send_call_history_save("call", strTimeStamp);
+                        mbCallState = false;
+                    }
+
+                    //String[] strEndIP = {"10.1.1.1", "10.1.1.2", "10.1.1.3", "10.1.1.4", "10.1.1.5", "10.1.1.6", "10.1.1.7"};
+
+                    for(int i = 0; i < strEndIP.length; i++)
+                    {
+                        if (strRemoteIP.equals(strEndIP[i])) {
+                            m_bCallStateThreadStop = false;
+                            Thread.sleep(1000);
+                            setTunkeyImage(i);
+                            break;
+                        }
+                    }
                 }
                 else if (eCallStatus == CALLSTATUS.HOMEVIEW) {
                     LOG_WARN("[onCallEvent] MOBILE HOMEVIEW!!!!");
@@ -634,7 +754,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     bRcvEnd = true;
 
                     if (eCallOwner != CALLOWNER.WALLPAD) {
-                        ((MainActivity) mContext).showRemoteCallNoticeText(false);
+                        //((MainActivity) mContext).showRemoteCallNoticeText(false);
                         ((MainActivity) mContext).finishPopUp(ID.POPUP.POPUP_NOTICE_SUBPHONETALK);
                     }
                     MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.RESIDENCE, CALLSTATUS.IDLE);
@@ -646,6 +766,13 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     MainActivity.mCallController.MultiCallScenarioManager();
                 } else if (eCallStatus == CALLSTATUS.REJECT) {
                     Global.stopMelodyRepeat();
+                    if(mbCallState)
+                    {
+                        String strTimeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
+                        send_call_history_save("reject_call", strTimeStamp);
+                        mbCallState = false;
+                    }
+
                     bRemoteVideoShow = false;
                     if (ConfigValues.bWallPadCameraEnable) {
                         prepareMyVideo(false);
@@ -667,6 +794,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     Global.change1stCallLogAction(CALLACTION.REJECT);
                     showMyVideo(false);
                     MainActivity.mCallController.MultiCallScenarioManager();
+
                 }
                 else if (eCallStatus == CALLSTATUS.BUSY) {
                     Global.stopMelodyRepeat();
@@ -718,6 +846,12 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     MainActivity.mCallController.stop1stCallTimer();
                     tryAutoCall(strMessage);
                 } else if (eCallStatus == CALLSTATUS.TIMEOUT_1STCALL) {
+                    if(mbCallState)
+                    {
+                        String strTimeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
+                        send_call_history_save("missed_call", strTimeStamp);
+                        mbCallState = false;
+                    }
                     Global.stopMelodyRepeat();
                     bRemoteVideoShow = false;
                     if (ConfigValues.bWallPadCameraEnable) {
@@ -736,6 +870,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     updateScreen();
                     showMyVideo(false);
                     MainActivity.mCallController.MultiCallScenarioManager();
+
                 } else {
                     Log.w(TAG, "[onCallEvent] Incorrect eCallStatus!!! eCallStatus = " + eCallStatus);
                 }
@@ -782,10 +917,10 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                                 if (MainActivity.mPSTNController != null) MainActivity.mPSTNController.stopPSTNRingCntThread(); // PSTN 멀티콜 거절시 ring cnt 초기화
                                 MainActivity.mCallController.stop2ndCallTimer();
                                 doMultiCallReject();
-                                if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
-                                    MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
-                                }
+//                                if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
+//                                    MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                                }
                                 sendHandlerMsgDelayed(HANDLERMSG.REFRESH_BTNLED_STATUS, 0, 0, 1000);
 
                                 if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
@@ -845,10 +980,10 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                                 if (MainActivity.mPSTNController != null) MainActivity.mPSTNController.stopPSTNRingCntThread(); // PSTN 멀티콜 거절시 ring cnt 초기화
                                 MainActivity.mCallController.stop2ndCallTimer();
                                 doMultiCallReject();
-                                if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
-                                    MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
-                                }
+//                                if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
+//                                    MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                                }
                                 sendHandlerMsgDelayed(HANDLERMSG.REFRESH_BTNLED_STATUS, 0, 0, 1000);
 
                                 if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
@@ -1114,10 +1249,10 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     if (MainActivity.mPSTNController != null) MainActivity.mPSTNController.stopPSTNRingCntThread(); // PSTN 멀티콜 거절시 ring cnt 초기화
                     MainActivity.mCallController.stop2ndCallTimer();
                     doMultiCallReject();
-                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
-                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
-                    }
+//                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
+//                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                    }
                     sendHandlerMsgDelayed(HANDLERMSG.REFRESH_BTNLED_STATUS, 0, 0, 1000);
 
                     if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
@@ -1127,11 +1262,11 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                         else ctrlAlphaBlending(false);
                     }
                 }
-                if (bFinish
-                        && (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40
-                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT))
-                    MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                if (bFinish
+//                        && (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40
+//                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                        || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT))
+                    //MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
             } else if (nScreen == ID.POPUP.POPUP_NOTICE_SUBPHONETALK) {
                 if (nID == ID.POPUP.NOTICE_SUBPHONETALK.ELEMENT.BUTTON.END) {
                     LOG_INFO("[onPopupResult] ID.POPUP.NOTICE_SUBPHONETALK.ELEMENT.BUTTON.END");
@@ -1141,10 +1276,10 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             } else if (nScreen == ID.POPUP.POPUP_MULTICALL_NOTICE) {
                 if (nID == ID.POPUP.MUTICALL_NOTICE.ELEMENT.BUTTON.CONFIRM) {
                     LOG_INFO("[onPopupResult] ID.POPUP.POPUP_MULTICALL_NOTICE.ELEMENT.BUTTON.CONFIRM");
-                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
-                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
-                    }
+//                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
+//                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                    }
 
                     /**
                      * JEFF, 2020.01.01
@@ -1153,10 +1288,10 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     if (MainActivity.mPSTNController != null) MainActivity.mPSTNController.stopPSTNRingCntThread(); // PSTN 멀티콜 거절시 ring cnt 초기화
                     MainActivity.mCallController.stop2ndCallTimer();
                     doMultiCallReject();
-                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
-                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
-                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
-                    }
+//                    if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
+//                            || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT) {
+//                        MainActivity.mIOInterface.ctrlPopupGUI_Resi(false, bshowMyVideo); // 현재 통화패스가 IHN-1010 이웃통화일 경우 멀티콜 거절시 GUI 화면이 아래로(영상이 위로)
+//                    }
                     sendHandlerMsgDelayed(HANDLERMSG.REFRESH_BTNLED_STATUS, 0, 0, 1000);
 
                     if (ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40 || ConfigValues.DEVICE_BOARDTYPE == BOARD_TYPE.V40_NOUGAT
@@ -1226,7 +1361,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     Log.e(TAG, "[Exception] doTalk -> EthernetCtrl.makeIPAddress(...)");
                     ((MainActivity) mContext).setMenuBTNEnable(true);
                     //e.printStackTrace();
-            LogUtil.errorLogInfo("", TAG, e);
+                    LogUtil.errorLogInfo("", TAG, e);
                 }
 
                 if (!send_check_sip_activation_request(RemoteIDInfo.strIP)) {
@@ -1237,6 +1372,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     return;
                 }
 
+
                 MainActivity.mCallController.mCallInfo.setCallOwner(eCallOwner);
                 MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.RESIDENCE, CALLSTATUS.TRYING_CALL);
             }
@@ -1585,14 +1721,14 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             int BOARDTYPE = ConfigValues.DEVICE_BOARDTYPE;
             if (BOARDTYPE == BOARD_TYPE.V40_IGW300 || BOARDTYPE == BOARD_TYPE.V40 || BOARDTYPE == BOARD_TYPE.V40_IGW300_NOUGAT || BOARDTYPE == BOARD_TYPE.V40_NOUGAT) {
                 if (bON) {
-                    IMG_VIDEO_MODULE.setImageResource(R.drawable.video_black_back);
+                    //IMG_VIDEO_MODULE.setImageResource(R.drawable.video_black_back);
                     MainActivity.mCallController.mVideoJNI.setPreviewInfo_V40(116, 85, 240, 160);
                 }
                 else {
-                    IMG_VIDEO_MODULE.setImageResource(R.drawable.image_neig);
+                    //IMG_VIDEO_MODULE.setImageResource(R.drawable.image_neig);
                     MainActivity.mCallController.mVideoJNI.setPreviewInfo_V40(0, 0, 0, 0);
                 }
-                MainActivity.mIOInterface.ctrlPopupGUI_Resi(!bON, bshowMyVideo);
+                //MainActivity.mIOInterface.ctrlPopupGUI_Resi(!bON, bshowMyVideo);
             }
             else {
                 Log.w(TAG, "[ctrlAlphaBlending] Not supported BOARDTYPE!! [" + BOARDTYPE + "]");
@@ -1649,6 +1785,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     BTN_TALK.setButtonEventOffEnable(R.drawable.btn_residence_call_disabled2);
                 }
                 showTalkMode(true);
+
                 setOnCallLED();
             } else if (MainActivity.mCallController.mCallInfo.getRESI() == CALLSTATUS.HOMEVIEW) {
                 ((MainActivity) mContext).setMenuBTNEnable(false);
@@ -1659,6 +1796,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                     BTN_TALK.setButtonEventOffEnable(R.drawable.btn_residence_call_disabled2);
                 }
                 showTalkMode(true);
+
             } else {
                 ((MainActivity) mContext).setMenuBTNEnable(true);
                 // 버튼 이미지 조작
@@ -1854,36 +1992,56 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             LOG("[showTalkMode] bTalk [" + bTalk + "]");
             if (bTalk) {
                 // 세대정보/안내문구
-                TXT_RESIDENCEINFO.setVisibility(View.INVISIBLE);
-                TXT_INSTRUCTION.setVisibility(View.INVISIBLE);
+//                TXT_RESIDENCEINFO.setVisibility(View.VISIBLE);
+//                TXT_INSTRUCTION.setVisibility(View.VISIBLE);
 
                 // 텐키 이미지 조작
-                IMG_VIDEO_MODULE.setVisibility(View.VISIBLE);
-                BTN_DELETE.setVisibility(View.INVISIBLE);
-                if (ConfigValues.bEnableHouseDivision) {
-                    if(BTN_DIVISION!=null)
-                        BTN_DIVISION.setVisibility(View.INVISIBLE);
-                }for (int i = 0; i < BTN_TENKEY.length; i++) {
-                    BTN_TENKEY[i].setVisibility(View.INVISIBLE);
-                }
+                //IMG_VIDEO_MODULE.setVisibility(View.VISIBLE);
+//                TXT_RESIDENCEINFO.setVisibility(View.VISIBLE);
+//                TXT_INSTRUCTION.setVisibility(View.VISIBLE);
+                //BTN_DELETE.setVisibility(View.INVISIBLE);
+//                if (ConfigValues.bEnableHouseDivision) {
+//                    if(BTN_DIVISION!=null)
+//                        BTN_DIVISION.setVisibility(View.INVISIBLE);
+//                }
+//                for (int i = 0; i < BTN_TENKEY.length; i++) {
+//                    BTN_TENKEY[i].setVisibility(View.INVISIBLE);
+//                }
 
                 // 통화상대 정보
-                ((MainActivity) mContext).displayRemoteID(RemoteIDInfo.strName);
+                ((MainActivity) mContext).displayRemoteID(null);
             } else {
                 // 세대정보/안내문구
-                TXT_RESIDENCEINFO.setVisibility(View.VISIBLE);
-                TXT_INSTRUCTION.setVisibility(View.VISIBLE);
 
-                // 텐키 이미지 조작
-                BTN_DELETE.setVisibility(View.VISIBLE);
-                if (ConfigValues.bEnableHouseDivision) {
-                    if(BTN_DIVISION!=null)
-                        BTN_DIVISION.setVisibility(View.VISIBLE);
-                }
-                for (int i = 0; i < BTN_TENKEY.length; i++) {
-                    if(BTN_TENKEY[i]!=null)
+                if(MainActivity.mCallController.mCallInfo.getRESI() == CALLSTATUS.IDLE)
+                {
+                    TXT_RESIDENCEINFO.setVisibility(View.INVISIBLE);
+                    TXT_INSTRUCTION.setVisibility(View.INVISIBLE);
+
+                    for (int i = 0; i < BTN_TENKEY.length; i++) {
                         BTN_TENKEY[i].setVisibility(View.VISIBLE);
+                    }
+
+                }
+                else
+                {
+//                    TXT_RESIDENCEINFO.setVisibility(View.VISIBLE);
+//                    TXT_INSTRUCTION.setVisibility(View.VISIBLE);
+                    for (int i = 0; i < BTN_TENKEY.length; i++) {
+                        BTN_TENKEY[i].setButtonEventOffEnable();
+                    }
                 }
+
+                // 텐키 이미지 조작
+                //BTN_DELETE.setVisibility(View.VISIBLE);
+//                if (ConfigValues.bEnableHouseDivision) {
+//                    if(BTN_DIVISION!=null)
+//                        BTN_DIVISION.setVisibility(View.VISIBLE);
+//                }
+//                for (int i = 0; i < BTN_TENKEY.length; i++) {
+//                    if(BTN_TENKEY[i]!=null)
+//                        BTN_TENKEY[i].setVisibility(View.VISIBLE);
+//                }
                 IMG_VIDEO_MODULE.setVisibility(View.INVISIBLE);
 
                 // 통화상대 정보
@@ -1916,7 +2074,7 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
                 } else {
                     BTN_PORTRAIT.setImageResource(R.drawable.btn_residence_me_normal3);
                 }
-                MainActivity.mIOInterface.ctrlPopupGUI_Resi(!bRemoteVideoShow, bshowMyVideo); // 세대통화 시작시 초기화
+                //MainActivity.mIOInterface.ctrlPopupGUI_Resi(!bRemoteVideoShow, bshowMyVideo); // 세대통화 시작시 초기화
             }
             else {
                 LOG_WARN("[showMyVideo] BTN_PORTRAIT is null!!");
@@ -1951,58 +2109,218 @@ public class TalkResidence extends WpadScreen implements CallEventListener, Main
             //e.printStackTrace();
             LogUtil.errorLogInfo("", TAG, e);
         }
+
+
+    }
+
+//    Handler mHandler = new Handler() ;
+//
+//    class CallStateThread extends Thread {
+//        Handler handler = mHandler ;
+//        int m_iVal = 0;
+//        int m_iVal1 = 0;
+//        boolean m_bImageSet = false;
+//        boolean m_bStop = true;
+//
+//        public void CallStateThread(int val)
+//        {
+//            m_iVal = val;
+//            if(m_nIDCnt_type < val)
+//                m_iVal1 = val - 1;
+//        }
+//
+//        public void ThreadStop()
+//        {
+//            m_bStop = false;
+//        }
+//
+//        @Override
+//        public void run() {
+//            while (m_bStop) {
+//                // create Runnable instance.
+//                Runnable runnable = new Runnable() {
+//                    @Override
+//                    public void run() {
+//                        // TODO : 실행 코드 작성.
+//                        if(m_bImageSet)
+//                        {
+//                            BTN_TENKEY[m_iVal1].setButtonDefaultImageID();
+//                            m_bImageSet = false;
+//                        }
+//                        else
+//                        {
+//                            BTN_TENKEY[m_iVal1].setButtonPressedImageID();
+//                            m_bImageSet = true;
+//                        }
+//
+//                        //BTN_TENKEY[m_iVal1].setImageResource(TENKEYS[m_iVal][2]);
+//                    }
+//                };
+//
+//                // send runnable object.
+//                handler.post(runnable) ;
+//
+//                try {
+//                    Thread.sleep(500);
+//                } catch (InterruptedException e) {
+//                    e.printStackTrace();
+//                }
+//            }
+//        }
+//
+//    }
+
+    class CallStateThread implements Runnable {
+
+        int m_iVal = 0;
+        int m_iImageSet = 0;
+
+        CallStateThread(int val) {
+
+            if(m_nIDCnt_type < val)
+                m_iVal = val - 1;
+            else
+                m_iVal = val;
+        }
+
+        public void run() {
+            // TODO : thread running codes.
+            while (m_bCallStateThreadStop) {
+
+                Message msg = handler.obtainMessage();
+
+                msg.arg1 = m_iVal;
+                msg.arg2 = m_iImageSet;
+                handler.sendMessage(msg);
+
+                if(m_iImageSet == 0) m_iImageSet = 1;
+                else if(m_iImageSet == 1) m_iImageSet = 0;
+
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+
+        }
+    }
+
+    final Handler handler = new Handler()
+
+    {
+        public void handleMessage(Message msg)
+        {
+            if(msg.arg2 == 0)
+            {
+                BTN_TENKEY[msg.arg1].setButtonPressedImageID();
+            }
+            else if(msg.arg2 == 1)
+            {
+                BTN_TENKEY[msg.arg1].setButtonDefaultImageID();
+            }
+        }
+
+    };
+
+
+    private void setTunkeyImage(int val)
+    {
+
+        int ival = 0;
+        if(m_nIDCnt_type < val)
+            ival = val - 1;
+        else
+            ival = val;
+
+
+        for(int i = 0; i < BTN_TENKEY.length; i++)
+        {
+
+            if(ival == i)
+            {
+                BTN_TENKEY[i].setImageResource(TENKEYS[val][2]);
+            }
+            else
+            {
+                BTN_TENKEY[i].setButtonDefaultImageID();
+            }
+        }
+
     }
 
     private void playTenkeyNo(int nBTN) {
         try {
-            int nSoundIndex = SND.number.NUM0;
+            int nSoundIndex = SND.effect.TOUCH_LATCHED;
             switch (nBTN) {
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_00:
-                    nSoundIndex = SND.number.NUM0;
+                    //nSoundIndex = SND.number.NUM0;
                     break;
-
+//String[] strEndIP = {"10.1.1.1", "10.1.2.1", "10.1.3.1", "10.1.3.2", "10.1.1.3", "10.1.1.2", "10.1.2.2"};
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_01:
-                    nSoundIndex = SND.number.NUM1;
+                    //nSoundIndex = SND.number.NUM1;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "101";
+
+                    setTunkeyImage(0);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_02:
-                    nSoundIndex = SND.number.NUM2;
+                    //nSoundIndex = SND.number.NUM2;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "201";
+                    setTunkeyImage(1);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_03:
-                    nSoundIndex = SND.number.NUM3;
+                    //nSoundIndex = SND.number.NUM3;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "301";
+                    setTunkeyImage(2);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_04:
-                    nSoundIndex = SND.number.NUM4;
+                    //nSoundIndex = SND.number.NUM4;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "302";
+                    setTunkeyImage(3);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_05:
-                    nSoundIndex = SND.number.NUM5;
+                    //nSoundIndex = SND.number.NUM5;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "103";
+                    setTunkeyImage(4);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_06:
-                    nSoundIndex = SND.number.NUM6;
+                    //nSoundIndex = SND.number.NUM6;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "102";
+                    setTunkeyImage(5);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_07:
-                    nSoundIndex = SND.number.NUM7;
+                    //nSoundIndex = SND.number.NUM7;
+                    RemoteIDInfo.strDong = "101";
+                    RemoteIDInfo.strHo = "202";
+                    setTunkeyImage(6);
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_08:
-                    nSoundIndex = SND.number.NUM8;
+                    //nSoundIndex = SND.number.NUM8;
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_09:
-                    nSoundIndex = SND.number.NUM9;
+                    //nSoundIndex = SND.number.NUM9;
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_DONG:
-                    nSoundIndex = SND.setting.DONG;
+                    //nSoundIndex = SND.setting.DONG;
                     break;
 
                 case ID.SCREEN.TALKRESIDENCE.ELEMENT.BUTTON.TENKEY_HO:
-                    nSoundIndex = SND.setting.HO;
+                    //nSoundIndex = SND.setting.HO;
                     break;
             }
 

+ 148 - 15
WallPadCall/src/main/java/kr/co/icontrols/wallpadcall/screen/VisitorPictureViewer.java

@@ -11,6 +11,8 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 
+import com.artncore.commons.define;
+import com.artncore.wallpadimap.RetProci;
 import com.util.LogUtil;
 
 import java.io.File;
@@ -25,11 +27,16 @@ import kr.co.icontrols.wallpadcall.MainActivity.MAINEVENT;
 import kr.co.icontrols.wallpadcall.MainActivity.MainEventListener;
 import kr.co.icontrols.wallpadcall.R;
 import kr.co.icontrols.wallpadcall.declare.Common;
+import kr.co.icontrols.wallpadcall.declare.DataClasses;
 import kr.co.icontrols.wallpadcall.declare.DataClasses.VisitorPictureHistoryInfoTable;
+import kr.co.icontrols.wallpadcall.declare.DataClasses.AllVisitorPictureHistoryInfoTable;
 import kr.co.icontrols.wallpadcall.declare.Declare;
 import kr.co.icontrols.wallpadcall.declare.Global;
 import kr.co.icontrols.wallpadcall.declare.Global.ConfigValues;
 import kr.co.icontrols.wallpadcall.declare.ID;
+import kr.co.icontrols.wallpadcall.imap.Request_call_history_delete;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_delete;
+import kr.co.icontrols.wallpadcall.imap.Request_visitor_picture_inquiry;
 import kr.co.icontrols.wallpadsupport.Version.MODEL_TYPE;
 import kr.co.icontrols.wallpadsupport.WpadImageView;
 import kr.co.icontrols.wallpadsupport.WpadImageView.TOUCH_KIND;
@@ -82,6 +89,7 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
     String strText_PageNo = "1/1";
 
     VisitorPictureHistoryInfoTable mVisitorPictureHistoryInfoTable = new VisitorPictureHistoryInfoTable();
+    AllVisitorPictureHistoryInfoTable mAllVisitorPictureHistoryInfoTable = new AllVisitorPictureHistoryInfoTable();
 
     public VisitorPictureViewer(Context context, RelativeLayout layout) {
         super(context, layout);
@@ -113,7 +121,9 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
             ViewRegistration(layout, TXT_PAGE, Common.ImgPosition.GetX(372), Common.ImgPosition.GetY(670));
 
             Initialize();
-            initVisitorPictureInfo(true);
+            m_bShowCount = true;
+            send_visitor_picture_inquiry("1", "60");
+
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {
@@ -234,7 +244,9 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CONFIRM");
                     if (strItemType.equals("VisitorPictureViewer_Delete")) {
                         deleteVisitorPicture(nCurrentPicture);
-                        initVisitorPictureInfo(false);
+                        m_bShowCount = false;
+                        send_visitor_picture_inquiry("1", "60");
+                        //initVisitorPictureInfo(false);
                     }
                 } else if (nID == ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL) {
                     LOG_INFO("[onPopupResult] ID.POPUP.DELETE_ITEMS.ELEMENT.BUTTON.CANCEL");
@@ -305,18 +317,102 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
         }
     }
 
+    int m_iCnt = 0;
+    boolean m_bShowCount = false;
+
+    private boolean send_visitor_picture_inquiry(String strPage, String strCount) {
+        try {
+            LOG_INFO("[send_visitor_picture_inquiry] strPage() "+ strPage + " strCount " + strCount);
+            final Request_visitor_picture_inquiry visitor_picture_inquiry = new Request_visitor_picture_inquiry(mContext);
+            if (visitor_picture_inquiry.send_visitor_picture_inquiry("101", "101", strPage, strCount)) {
+                visitor_picture_inquiry.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+                        //nHistoryCnt = MainActivity.mVisitorPictureHistoryManager.getHistoryCnt(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE);
+                        //LOG("[initHistoryPageInfo] nHistoryCnt = " + nHistoryCnt);
+                        //nTotalPage = ((nHistoryCnt + LIST_CNT - 1) / LIST_CNT);
+                        //LOG("[initHistoryPageInfo] nTotalPage = " + nTotalPage);
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcSuccess()");
+                        visitor_picture_inquiry.SetItem("inquiry_info");
+                        int nQuantity = Integer.parseInt(visitor_picture_inquiry.GetAttributeVal(0, "quantity"));
+                        mVisitorPictureHistoryInfoTable.clearTable();
+                        mAllVisitorPictureHistoryInfoTable.clearTable();
+                        visitor_picture_inquiry.SetItem("visitor_pic");
+                        for(int i = 0; i < nQuantity; i++)
+                        {
+                            //LOG_INFO("[send_call_history_inquiry] " + i + " " + call_history_inquiry.GetAttributeVal(i, "event_time"));
+
+                            String strName = visitor_picture_inquiry.GetAttributeVal(i, "filename");
+                            String strPath = visitor_picture_inquiry.GetAttributeVal(i, "path");
+                            String strReply_Path = strPath;
+                            String strTimestamp = visitor_picture_inquiry.GetAttributeVal(i, "time");
+                            String strURI = define.VISITOR_PICTURE_LOCATION + "/" + strName;
+                            //LOG_INFO("[send_call_history_inquiry] strURI " + i + " " + strURI);
+
+                            mVisitorPictureHistoryInfoTable.addVisitorPictureHistoryInfo(String.valueOf(i), strName, "", "", "", strURI, "", strTimestamp);
+
+                            mAllVisitorPictureHistoryInfoTable.addVisitorPictureHistoryInfo(visitor_picture_inquiry.GetAttributeVal(i, "dong"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "ho"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "time"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "path"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "filename"),
+                                    visitor_picture_inquiry.GetAttributeVal(i, "message")
+                            );
+                        }
+
+                        m_iCnt = nQuantity;
+
+                        initVisitorPictureInfo(m_bShowCount);
+                        LOG_INFO("[send_visitor_picture_inquiry] m_iCnt " + m_iCnt);
+
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
+
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_visitor_picture_inquiry] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_visitor_picture_inquiry(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
     private void initVisitorPictureInfo(boolean bScreenCreated) {
         try {
             LOG_INFO("[initVisitorPictureInfo]");
-            mVisitorPictureHistoryInfoTable.clearTable();
-            mVisitorPictureHistoryInfoTable = MainActivity.mVisitorPictureHistoryManager.getVisitorPictureHistory_All();
-            if (mVisitorPictureHistoryInfoTable == null) {
+            //mVisitorPictureHistoryInfoTable.clearTable();
+            //mVisitorPictureHistoryInfoTable = MainActivity.mVisitorPictureHistoryManager.getVisitorPictureHistory_All();
+
+//            int iCount = 0;
+//            while (iCount < 100)
+//            {
+//                if(m_bResponse == true)
+//                    break;
+//                Thread.sleep(100);
+//                iCount++;
+//            }
+//            m_bResponse = false;
+
+            LOG_INFO("[send_visitor_picture_inquiry]  1 m_iCnt " + m_iCnt);
+            nTotalPicture = m_iCnt;
+            if (nTotalPicture == 0) {
                 strText_PageNo = "0/0";
                 TXT_PAGE.setText(strText_PageNo);
                 IMG_PICTURE.setImageResource(R.drawable.visitor_picture_bg);
                 return;
             }
-            nTotalPicture = mVisitorPictureHistoryInfoTable.getCnt();
+
             if (bScreenCreated) nCurrentPicture = getStartPictureIndex(Global.strVisitorPictureID);
             if (nCurrentPicture > nTotalPicture) nCurrentPicture = nTotalPicture;
             LOG_INFO("[initVisitorPictureInfo] nCurrentPicture = " + nCurrentPicture + ", nTotalPicture = " + nTotalPicture);
@@ -333,8 +429,8 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
 
     private int getStartPictureIndex(String strID) {
         try {
-            LOG_INFO("[drawInitVisitorPicture] strID [" + strID + "]");
-            int nCnt = mVisitorPictureHistoryInfoTable.getCnt();
+            LOG_INFO("[drawInitVisitorPicture] strID [" + strID + "] m_iCnt [" + m_iCnt + "]");
+            int nCnt = m_iCnt;
             for (int i = 0; i < nCnt; i++) {
                 if (strID.equals(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(i).getID())) {
                     return i + 1;
@@ -400,15 +496,52 @@ public class VisitorPictureViewer extends WpadScreen implements CallEventListene
         }
     }
 
-    private void deleteVisitorPicture(int nIndex) {
+    private boolean send_visitor_picture_delete(String strMsg, String strCount) {
         try {
-            ArrayList<String> SelectedIDs = new ArrayList<String>();
-            ArrayList<String> SelectedURIs = new ArrayList<String>();
-            SelectedIDs.add(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nIndex - 1).getID());
-            SelectedURIs.add(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nIndex - 1).getURI());
+            LOG_INFO("[send_visitor_picture_delete] strType() "+ strMsg + " strCount " + strCount);
+            final Request_visitor_picture_delete visitor_picture_delete = new Request_visitor_picture_delete(mContext);
+            if (visitor_picture_delete.send_visitor_picture_delete(strMsg, strCount)) {
+                visitor_picture_delete.setResultCtrl(new RetProci() {
+
+                    @Override
+                    public void ProcSuccess() {
+
+                        LOG_INFO("[send_visitor_picture_delete] ProcSuccess() ");
+                    }
+
+                    @Override
+                    public void ProcError() {
+                        LOG_INFO("[send_visitor_picture_delete] ProcError()");
+                        //MainActivity.mCallController.mSIPInterface.cancelCallForwardToStun();
+                    }
 
-            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE, SelectedIDs);
-            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(SelectedURIs);
+                    @Override
+                    public void ProcDoing() {
+                        LOG_INFO("[send_visitor_picture_delete] ProcDoing()");
+                    }
+                });
+                return true;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] send_visitor_picture_delete(String strTargetIP, String strMessage)");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    private void deleteVisitorPicture(int nIndex) {
+        try {
+            LOG_INFO("[deleteVisitorPicture] nIndex " + nIndex);
+
+            String strMsg = mAllVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nIndex-1).getData();
+            send_visitor_picture_delete(strMsg,"1");
+//            ArrayList<String> SelectedIDs = new ArrayList<String>();
+//            ArrayList<String> SelectedURIs = new ArrayList<String>();
+//            SelectedIDs.add(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nIndex - 1).getID());
+//            SelectedURIs.add(mVisitorPictureHistoryInfoTable.getVisitorPictureHistoryInfo(nIndex - 1).getURI());
+//
+//            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(Declare.DBInfo.TABLE_NAME_HISTORY_VISITORPICTURE, SelectedIDs);
+//            MainActivity.mVisitorPictureHistoryManager.deleteHistoryList(SelectedURIs);
         } catch (RuntimeException re) {
             LogUtil.errorLogInfo("", TAG, re);
         } catch (Exception e) {

+ 3 - 1
WallPadMain/src/main/java/kr/co/icontrols/wallpadmain/MainActivity.java

@@ -164,7 +164,9 @@ import static com.artncore.commons.define.BESTIN_LOCATION;
  */
 public class MainActivity extends WpadActivity {
     private final static String TAG = "MainActivity";
-    
+    //git test code
+    private int miTest = 1;
+
     private void DebugLogOutput(String s) { if(Common.DEBUG_LOG_ON) Log.d(TAG, s); }
 
     // =================================================================================================

+ 91 - 0
WallPadMain/src/main/java/kr/co/icontrols/wallpadmain/util/iMapServer.java

@@ -3134,6 +3134,23 @@ public class iMapServer extends Service {
         }
     }
 
+    public String getRemoteIPAddress(Socket Sock) {
+        try {
+//            Log.i(TAG, "[getRemoteIPAddress] == START ==");
+            if (Sock == null) return "10.0.1.1";
+
+            String strRemoteIP = Sock.getRemoteSocketAddress().toString();
+            String[] strSplited_01 = strRemoteIP.split(":");
+            String[] strSplited_02 = strSplited_01[0].split("/");
+            strRemoteIP = strSplited_02[1];
+            return strRemoteIP;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] getRemoteIPAddress(Sock)");
+            e.printStackTrace();
+            return "10.0.1.1";
+        }
+    }
+
     // iMAP 서버 소켓 처리
 	public class iMapSverSocketThread extends Thread {
 		private final Socket iMAPSock;
@@ -3422,6 +3439,9 @@ public class iMapServer extends Service {
                             String sip_result = "fail";
 							ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
 							List<ActivityManager.RunningServiceInfo> rsi = manager.getRunningServices(50);
+                            //add KSJ 2021.11.02 socket addr 가져오기 위해 추가
+							String strIP = getRemoteIPAddress(iMAPSock);
+                            //~add KSJ
 
 							// Jeff added below codes for call app (2018.01.25)
 							String strSIPPackageName = "kr.co.icontrols.callengine.sip.SIPStun";
@@ -3434,7 +3454,40 @@ public class iMapServer extends Service {
 								}
 							}
 							retXML = XMLHeader + "<service type=\"reply\" name=\"check_sip_activation\" result=\"" + sip_result + "\">\r\n    <message>\"null\"</message>\r\n</service>\r\n</imap>\r\n";
+
+                            //add KSJ 2021.11.02 check_sip_activation msg recv 이후 wallpadcall app start
+							String[] IP_Parse = strIP.split("\\.");
+                            Log.d(TAG, "1" + strIP);
+                            //Log.d(TAG, "2" + strSplit[1]);
+                            //Log.d(TAG, "3" + strSplit[2]);
+                            //Log.d(TAG, "4" + strSplit[3]);
+                            CALLTYPE eCallType = CALLTYPE.LOBBY;
+                            if(IP_Parse[2].equals("0"))
+                            {
+
+                                eCallType = CALLTYPE.LOBBY;
+
+                                if(IP_Parse[3].equals("11"))
+                                    eCallType = CALLTYPE.FRONT;
+
+                            }
+                            else if(IP_Parse[2].equals("129"))
+                            {
+                                eCallType = CALLTYPE.FRONT;
+                            }
+                            else
+                            {
+                                eCallType = CALLTYPE.RESIDENCE;
+                            }
+
+                            if((eCallType == CALLTYPE.LOBBY) || (eCallType == CALLTYPE.FRONT))
+                                runCallMainActivity_moip(CALLEVENTTYPE.RECEIVE_CALL, eCallType, strIP);
 						}
+						//add KSJ 2021.11.02 stop_talking msg 추가 (wallpadcall 종료)
+                        else if (cmd.equals("stop_talking")) {
+                            Common.SendAppFinishReqBR(getApplicationContext());
+                        }
+                        //~add KSJ
 						else if (cmd.equalsIgnoreCase("remote_get_home_devices")) {
 							retXML = iCMDProcDevList(doc);
 						}
@@ -14305,6 +14358,7 @@ public class iMapServer extends Service {
         public static String CALLOWNER = "CALLOWNER";
         public static String CALLEVENTTYPE = "CALLEVENTTYPE";
         public static String CALLTYPE = "CALLTYPE";
+        public static String REMOTEINFO = "REMOTEINFO"; //add KSJ 2021.11.02
         public enum SOURCE {
             USER,
             CALL_RECEIVE,
@@ -14357,6 +14411,43 @@ public class iMapServer extends Service {
         }
     }
 
+    //add KSJ 2021.11.02
+    public void runCallMainActivity_moip(CALLEVENTTYPE eEventType, CALLTYPE eCallType, String strIP) {
+        try {
+            if (!bWallPadCallLive) {
+                // 통화어플을 실행시킨다.
+                Log.w(TAG, "[runCallMainActivity_moip] ########## START ##########");
+                sendLCDBacklightStatus(true);
+
+                WallpadStatusData mWallpadStatusData = new WallpadStatusData(getApplicationContext());
+                int nAlramStatus = mWallpadStatusData.GetAlarmStatus();
+                mWallpadStatusData.closeDB();
+
+                if (nAlramStatus != WallpadStatusData.GUARD_OUT) Common.SendAppFinishReqBR(getApplicationContext());
+
+                ComponentName mComponentName = new ComponentName("kr.co.icontrols.wallpadcall", "kr.co.icontrols.wallpadcall.MainActivity");
+                Intent mIntent = new Intent(Intent.ACTION_MAIN);
+                mIntent.putExtra(CALLTRIGGER.CALLOWNER, CALLOWNER.NONE.toString());
+                mIntent.putExtra(CALLTRIGGER.CALLEVENTTYPE, eEventType.toString());
+                mIntent.putExtra(CALLTRIGGER.CALLTYPE, eCallType.toString());
+                mIntent.putExtra(CALLTRIGGER.REMOTEINFO, strIP);
+                mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                mIntent.setComponent(mComponentName);
+                startActivity(mIntent);
+                Thread.sleep(500);   // Call app이 실행되는 시간을 기다려준다. (빨리 띄우면 이벤트를 수신 못함)
+            } else {
+                Log.w(TAG, "[runCallMainActivity_moip] WallPadCall is already running!!");
+            }
+        } catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] runCallMainActivity()");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+        }
+    }
+    //~add KSJ
+
     private String getTopActivity() {
         try {
             ActivityManager mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

Some files were not shown because too many files changed in this diff