Index: /pjproject/branches/projects/uwp/aconfigure
===================================================================
--- /pjproject/branches/projects/uwp/aconfigure	(revision 5531)
+++ /pjproject/branches/projects/uwp/aconfigure	(revision 5532)
@@ -642,11 +642,7 @@
 ac_no_opencore_amrwb
 ac_no_opencore_amrnb
-ec_curve_present
-set_curve_present
 libcrypto_present
 libssl_present
 openssl_h_present
-ac_ssl_has_sigalg
-ac_ssl_has_ec
 ac_ssl_has_aes_gcm
 ac_no_ssl
@@ -760,4 +756,5 @@
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
@@ -882,4 +879,5 @@
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
@@ -1134,4 +1132,13 @@
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
@@ -1271,5 +1278,5 @@
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
@@ -1424,4 +1431,5 @@
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
@@ -2345,5 +2353,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
@@ -2488,5 +2496,5 @@
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
 esac
 build=$ac_cv_build
@@ -2521,5 +2529,5 @@
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
 esac
 host=$ac_cv_host
@@ -2554,5 +2562,5 @@
 case $ac_cv_target in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
 esac
 target=$ac_cv_target
@@ -2891,5 +2899,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
@@ -3006,5 +3014,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -3049,5 +3057,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
@@ -3108,5 +3116,5 @@
 as_fn_error $? "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
@@ -3160,5 +3168,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
@@ -4554,5 +4562,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
@@ -5044,5 +5052,5 @@
    *)
      as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5  ;;
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
  esac
 
@@ -7617,5 +7625,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Error: unable to recognize your IPP installation. Make sure the paths and ARCH suffix are set correctly, run with --help for more info
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f core conftest.err conftest.$ac_objext \
@@ -7673,5 +7681,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Unable to find to find built binaries under $IPPSAMPLES/speech-codecs/{bin,_bin}. Have you built the IPP samples?
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 	    fi
 	else
@@ -7679,5 +7687,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "unable to find $IPPSAMPLES/speech-codecs/bin/*gcc*/lib or $IPPSAMPLES/speech-codecs/_bin/*gcc*/lib directory. Have you built the samples?
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 	fi
 
@@ -7687,5 +7695,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "There's something wrong with this script, directory $IPPSAMP_DIR does not exist
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 	    exit 1;
 	fi
@@ -7701,5 +7709,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "bug in this script: unsupported IPP version
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 	fi
 
@@ -7708,5 +7716,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "$IPPSAMP_LIBS doesn't exist in $IPPSAMP_DIR
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 	fi
 
@@ -7744,5 +7752,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f core conftest.err conftest.$ac_objext \
@@ -7789,8 +7797,4 @@
 
 ac_ssl_has_aes_gcm=0
-
-ac_ssl_has_ec=0
-
-ac_ssl_has_sigalg=0
 
 # Check whether --enable-ssl was given.
@@ -7955,118 +7959,4 @@
 $as_echo "OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos" >&6; }
 			fi
-
-			# Check if OpenSSL supports setting curve algorithm
-			# and has elliptic curve
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL setting curve functions" >&5
-$as_echo_n "checking OpenSSL setting curve functions... " >&6; }
-			set_curve_present=0
-
-			ec_curve_present=0
-
-			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <openssl/ssl.h>
-
-int
-main ()
-{
- SSL_set1_curves(NULL, NULL, 0);
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-   set_curve_present=1
-		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-
-else
-
-		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EC_curve_nid2nist in -lssl" >&5
-$as_echo_n "checking for EC_curve_nid2nist in -lssl... " >&6; }
-if ${ac_cv_lib_ssl_EC_curve_nid2nist+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char EC_curve_nid2nist ();
-int
-main ()
-{
-return EC_curve_nid2nist ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_ssl_EC_curve_nid2nist=yes
-else
-  ac_cv_lib_ssl_EC_curve_nid2nist=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_EC_curve_nid2nist" >&5
-$as_echo "$ac_cv_lib_ssl_EC_curve_nid2nist" >&6; }
-if test "x$ac_cv_lib_ssl_EC_curve_nid2nist" = xyes; then :
-  ec_curve_present=1
-fi
-
-			if test "x$set_curve_present" = "x1" -a "x$ec_curve_present" = "x1"; then
-				ac_ssl_has_ec=1
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL has elliptic curve support" >&5
-$as_echo "OpenSSL has elliptic curve support" >&6; }
-			else
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL elliptic curve algorithm unsupported" >&5
-$as_echo "OpenSSL elliptic curve algorithm unsupported" >&6; }
-			fi
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL setting sigalg" >&5
-$as_echo_n "checking OpenSSL setting sigalg... " >&6; }
-			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <openssl/ssl.h>
-
-int
-main ()
-{
-SSL_set1_sigalgs_list(NULL, NULL);
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-   ac_ssl_has_sigalg=1
-		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-
-else
-
-		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
 
 			# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK
@@ -9400,5 +9290,5 @@
     "third_party/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES third_party/build/os-auto.mak" ;;
 
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
@@ -9717,5 +9607,5 @@
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
@@ -9745,5 +9635,5 @@
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
@@ -9772,5 +9662,5 @@
     case $ac_tag in
     *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
Index: /pjproject/branches/projects/uwp/aconfigure.ac
===================================================================
--- /pjproject/branches/projects/uwp/aconfigure.ac	(revision 5531)
+++ /pjproject/branches/projects/uwp/aconfigure.ac	(revision 5532)
@@ -1534,6 +1534,4 @@
 AC_SUBST(ac_no_ssl)
 AC_SUBST(ac_ssl_has_aes_gcm,0)
-AC_SUBST(ac_ssl_has_ec,0)
-AC_SUBST(ac_ssl_has_sigalg,0)
 AC_ARG_ENABLE(ssl,
 	      AS_HELP_STRING([--disable-ssl],
@@ -1570,41 +1568,4 @@
 				AC_MSG_RESULT([OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos])
 			fi
-
-			# Check if OpenSSL supports setting curve algorithm
-			# and has elliptic curve
-			
-			AC_MSG_CHECKING([OpenSSL setting curve functions])
-			AC_SUBST(set_curve_present,0)
-			AC_SUBST(ec_curve_present,0)
-			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <openssl/ssl.h>
-					          ]],
-					          [ SSL_set1_curves(NULL, NULL, 0);]
-					         )],
-		  		 [ set_curve_present=1
-		  		   AC_MSG_RESULT(ok)
-		  		  ],
-		  		 [
-		  		   AC_MSG_RESULT(no)
-		  		 ])
-
-			AC_CHECK_LIB(ssl,EC_curve_nid2nist,[ec_curve_present=1])
-			if test "x$set_curve_present" = "x1" -a "x$ec_curve_present" = "x1"; then
-				[ac_ssl_has_ec=1]
-				AC_MSG_RESULT([OpenSSL has elliptic curve support])
-			else
-				AC_MSG_RESULT([OpenSSL elliptic curve algorithm unsupported])
-			fi
-
-			AC_MSG_CHECKING([OpenSSL setting sigalg])
-			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <openssl/ssl.h>
-					          ]],
-					          [SSL_set1_sigalgs_list(NULL, NULL);]
-					         )],
-		  		 [ ac_ssl_has_sigalg=1
-		  		   AC_MSG_RESULT(ok)
-		  		  ],
-		  		 [
-		  		   AC_MSG_RESULT(no)
-		  		 ])
 
 			# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK
Index: /pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in	(revision 5532)
@@ -33,10 +33,2 @@
 export TARGETS	    =	$(PJLIB_LIB) $(PJLIB_SONAME)
 export TARGETS_EXE  =   $(TEST_EXE)
-
-ifeq (@ac_ssl_has_ec@,1)
-export PJLIB_CFLAGS += -DPJ_SSL_SOCK_OSSL_HAS_EC=1
-endif
-
-ifeq (@ac_ssl_has_sigalg@,1)
-export PJLIB_CFLAGS += -DPJ_SSL_SOCK_OSSL_HAS_SIGALG=1
-endif
Index: /pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h	(revision 5532)
@@ -393,7 +393,4 @@
     #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY	5
     
-    /* Increase number of video device's supported formats */
-    #define PJMEDIA_VID_DEV_INFO_FMT_CNT	128
-
     /*
      * PJSIP settings.
Index: /pjproject/branches/projects/uwp/pjlib/include/pj/string.h
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/include/pj/string.h	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/include/pj/string.h	(revision 5532)
@@ -475,4 +475,91 @@
 }
 
+
+/**
+ * Find the first index of character, in a string, that does not belong to a 
+ * set of characters.
+ *
+ * @param str	    The string.
+ * @param set_char  The string containing the set of characters. 
+ *
+ * @return the index of the first character in the str that doesn't belong to 
+ * set_char. If str starts with a character not in set_char, return 0.
+ */
+PJ_DECL(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char);
+
+
+/**
+ * Find the first index of character, in a string, that does not belong to a
+ * set of characters.
+ *
+ * @param str	    The string.
+ * @param set_char  The string containing the set of characters.
+ *
+ * @return the index of the first character in the str that doesn't belong to
+ * set_char. If str starts with a character not in set_char, return 0.
+ */
+PJ_DECL(pj_ssize_t) pj_strspn2(const pj_str_t *str, const char *set_char);
+
+
+/**
+ * Find the first index of character, in a string, that belong to a set of 
+ * characters.
+ *
+ * @param str	    The string.
+ * @param set_char  The string containing the set of characters.
+ *
+ * @return the index of the first character in the str that belong to
+ * set_char. If no match is found, return the length of str.
+ */
+PJ_DECL(pj_ssize_t) pj_strcspn(const pj_str_t *str, const pj_str_t *set_char);
+
+
+/**
+ * Find the first index of character, in a string, that belong to a set of
+ * characters.
+ *
+ * @param str	    The string.
+ * @param set_char  The string containing the set of characters.
+ *
+ * @return the index of the first character in the str that belong to
+ * set_char. If no match is found, return the length of str.
+ */
+PJ_DECL(pj_ssize_t) pj_strcspn2(const pj_str_t *str, const char *set_char);
+
+
+/**
+ * Find tokens from a string using the delimiter.
+ *
+ * @param str	    The string.
+ * @param delim	    The string containing the delimiter. It might contain 
+ *		    multiple character treated as unique set. If same character
+ *		    was found on the set, it will be skipped.
+ * @param tok	    The string containing the token.
+ * @param start_idx The search will start from this index.
+ *
+ * @return the index of token from the str, or the length of the str
+ * if the token is not found.
+ */
+PJ_DECL(pj_ssize_t) pj_strtok(const pj_str_t *str, const pj_str_t *delim,
+			      pj_str_t *tok, pj_size_t start_idx);
+
+
+/**
+ * Find tokens from a string using the delimiter.
+ *
+ * @param str	    The string.
+ * @param delim	    The string containing the delimiter. It might contain
+ *		    multiple character treated as unique set. If same character
+ *		    was found on the set, it will be skipped.
+ * @param tok	    The string containing the token.
+ * @param start_idx The search will start from this index.
+ *
+ * @return the index of token from the str, or the length of the str
+ * if the token is not found.
+ */
+PJ_DECL(pj_ssize_t) pj_strtok2(const pj_str_t *str, const char *delim,
+			       pj_str_t *tok, pj_size_t start_idx);
+
+
 /**
  * Find the occurence of a substring substr in string str.
Index: /pjproject/branches/projects/uwp/pjlib/src/pj/os_info.c
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/src/pj/os_info.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/src/pj/os_info.c	(revision 5532)
@@ -99,8 +99,9 @@
 
 static pj_uint32_t parse_version(char *str)
-{
-    char *tok;
-    int i, maxtok;
+{    
+    int i, maxtok, found_idx;
     pj_uint32_t version = 0;
+    pj_str_t in_str = pj_str(str);
+    pj_str_t token, delim;
     
     while (*str && !pj_isdigit(*str))
@@ -108,13 +109,16 @@
 
     maxtok = 4;
-    for (tok = strtok(str, ".-"), i=0; tok && i<maxtok;
-	 ++i, tok=strtok(NULL, ".-"))
+    delim = pj_str(".-");
+    for (found_idx = pj_strtok(&in_str, &delim, &token, 0), i=0; 
+	 found_idx != in_str.slen && i < maxtok;
+	 ++i, found_idx = pj_strtok(&in_str, &delim, &token, 
+	                            found_idx + token.slen))
     {
 	int n;
 
-	if (!pj_isdigit(*tok))
-	    break;
-	
-	n = atoi(tok);
+	if (!pj_isdigit(*token.ptr))
+	    break;
+	
+	n = atoi(token.ptr);
 	version |= (n << ((3-i)*8));
     }
Index: /pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c	(revision 5532)
@@ -52,8 +52,61 @@
 #include <openssl/rand.h>
 #include <openssl/engine.h>
-
-#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
-   extern int tls1_ec_nid2curve_id(int nid);
-   extern int tls1_ec_curve_id2nid(int curve_id);
+#include <openssl/opensslconf.h>
+
+#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL
+
+#   include <openssl/obj_mac.h>
+
+static const unsigned nid_cid_map[] = {
+    NID_sect163k1,              /* sect163k1 (1) */
+    NID_sect163r1,              /* sect163r1 (2) */
+    NID_sect163r2,              /* sect163r2 (3) */
+    NID_sect193r1,              /* sect193r1 (4) */
+    NID_sect193r2,              /* sect193r2 (5) */
+    NID_sect233k1,              /* sect233k1 (6) */
+    NID_sect233r1,              /* sect233r1 (7) */
+    NID_sect239k1,              /* sect239k1 (8) */
+    NID_sect283k1,              /* sect283k1 (9) */
+    NID_sect283r1,              /* sect283r1 (10) */
+    NID_sect409k1,              /* sect409k1 (11) */
+    NID_sect409r1,              /* sect409r1 (12) */
+    NID_sect571k1,              /* sect571k1 (13) */
+    NID_sect571r1,              /* sect571r1 (14) */
+    NID_secp160k1,              /* secp160k1 (15) */
+    NID_secp160r1,              /* secp160r1 (16) */
+    NID_secp160r2,              /* secp160r2 (17) */
+    NID_secp192k1,              /* secp192k1 (18) */
+    NID_X9_62_prime192v1,       /* secp192r1 (19) */
+    NID_secp224k1,              /* secp224k1 (20) */
+    NID_secp224r1,              /* secp224r1 (21) */
+    NID_secp256k1,              /* secp256k1 (22) */
+    NID_X9_62_prime256v1,       /* secp256r1 (23) */
+    NID_secp384r1,              /* secp384r1 (24) */
+    NID_secp521r1,              /* secp521r1 (25) */
+    NID_brainpoolP256r1,        /* brainpoolP256r1 (26) */
+    NID_brainpoolP384r1,        /* brainpoolP384r1 (27) */
+    NID_brainpoolP512r1         /* brainpoolP512r1 (28) */
+};
+
+static unsigned get_cid_from_nid(unsigned nid)
+{
+    unsigned i, cid = 0;
+    for (i=0; i<PJ_ARRAY_SIZE(nid_cid_map); ++i) {
+	if (nid == nid_cid_map[i]) {
+	    cid = i+1;
+	    break;
+	}
+    }
+    return cid;
+};
+
+static unsigned get_nid_from_cid(unsigned cid)
+{
+    if ((cid == 0) || (cid > PJ_ARRAY_SIZE(nid_cid_map)))
+	return 0;
+
+    return nid_cid_map[cid-1];
+}
+
 #endif
 
@@ -386,5 +439,5 @@
 	ssl->session = SSL_SESSION_new();
 
-#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
+#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL
 	openssl_curves_num = SSL_get_shared_curve(ssl,-1);
 	if (openssl_curves_num > PJ_ARRAY_SIZE(openssl_curves))
@@ -403,5 +456,5 @@
 	    }
 
-	    openssl_curves[i].id   = tls1_ec_nid2curve_id(nid);
+	    openssl_curves[i].id   = get_cid_from_nid(nid);
 	    openssl_curves[i].name = cname;
 	}
@@ -1002,8 +1055,8 @@
 static pj_status_t set_curves_list(pj_ssl_sock_t *ssock)
 {
-#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
+#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL
     int ret;
     int curves[PJ_SSL_SOCK_MAX_CURVES];
-    int cnt;
+    unsigned cnt;
 
     if (ssock->param.curves_num == 0)
@@ -1011,5 +1064,5 @@
 
     for (cnt = 0; cnt < ssock->param.curves_num; cnt++) {
-	curves[cnt] = tls1_ec_curve_id2nid(ssock->param.curves[cnt]);
+	curves[cnt] = get_nid_from_cid(ssock->param.curves[cnt]);
     }
 
@@ -1028,5 +1081,4 @@
     PJ_UNUSED_ARG(ssock);
 #endif
-
     return PJ_SUCCESS;
 }
@@ -1034,5 +1086,5 @@
 static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock)
 {
-#if defined(PJ_SSL_SOCK_OSSL_HAS_SIGALG) && PJ_SSL_SOCK_OSSL_HAS_SIGALG==1
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
     int ret;
 
@@ -1052,5 +1104,4 @@
     PJ_UNUSED_ARG(ssock);
 #endif
-
     return PJ_SUCCESS;
 }
Index: /pjproject/branches/projects/uwp/pjlib/src/pj/string.c
===================================================================
--- /pjproject/branches/projects/uwp/pjlib/src/pj/string.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjlib/src/pj/string.c	(revision 5532)
@@ -29,4 +29,111 @@
 #endif
 
+PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char)
+{
+    pj_ssize_t i, j, count = 0;
+    for (i = 0; i < str->slen; i++) {
+	if (count != i) 
+	    break;
+
+	for (j = 0; j < set_char->slen; j++) {
+	    if (str->ptr[i] == set_char->ptr[j])
+		count++;
+	}
+    }
+    return count;
+}
+
+
+PJ_DEF(pj_ssize_t) pj_strspn2(const pj_str_t *str, const char *set_char)
+{
+    pj_ssize_t i, j, count = 0;
+    for (i = 0; i < str->slen; i++) {
+	if (count != i)
+	    break;
+
+	for (j = 0; set_char[j] != 0; j++) {
+	    if (str->ptr[i] == set_char[j])
+		count++;
+	}
+    }
+    return count;
+}
+
+
+PJ_DEF(pj_ssize_t) pj_strcspn(const pj_str_t *str, const pj_str_t *set_char)
+{
+    pj_ssize_t i, j;
+    for (i = 0; i < str->slen; i++) {
+	for (j = 0; j < set_char->slen; j++) {
+	    if (str->ptr[i] == set_char->ptr[j])
+		return i;
+	}
+    }
+    return i;
+}
+
+
+PJ_DECL(pj_ssize_t) pj_strcspn2(const pj_str_t *str, const char *set_char)
+{
+    pj_ssize_t i, j;
+    for (i = 0; i < str->slen; i++) {
+	for (j = 0; set_char[j] != 0; j++) {
+	    if (str->ptr[i] == set_char[j])
+		return i;
+	}
+    }
+    return i;
+}
+
+
+PJ_DEF(pj_ssize_t) pj_strtok(const pj_str_t *str, const pj_str_t *delim,
+			     pj_str_t *tok, pj_size_t start_idx)
+{    
+    pj_ssize_t str_idx;
+
+    tok->slen = 0;
+    if ((str->slen == 0) || ((pj_size_t)str->slen < start_idx)) {
+	return str->slen;
+    }
+    
+    tok->ptr = str->ptr + start_idx;
+    tok->slen = str->slen - start_idx;
+
+    str_idx = pj_strspn(tok, delim);
+    if (start_idx+str_idx == (pj_size_t)str->slen) {
+	return str->slen;
+    }    
+    tok->ptr += str_idx;
+    tok->slen -= str_idx;
+
+    tok->slen = pj_strcspn(tok, delim);
+    return start_idx + str_idx;
+}
+
+
+PJ_DECL(pj_ssize_t) pj_strtok2(const pj_str_t *str, const char *delim,
+			       pj_str_t *tok, pj_size_t start_idx)
+{
+    pj_ssize_t str_idx;
+
+    tok->slen = 0;
+    if ((str->slen == 0) || ((pj_size_t)str->slen < start_idx)) {
+	return str->slen;
+    }
+
+    tok->ptr = str->ptr + start_idx;
+    tok->slen = str->slen - start_idx;
+
+    str_idx = pj_strspn2(tok, delim);
+    if (start_idx + str_idx == (pj_size_t)str->slen) {
+	return str->slen;
+    }
+    tok->ptr += str_idx;
+    tok->slen -= str_idx;
+
+    tok->slen = pj_strcspn2(tok, delim);
+    return start_idx + str_idx;
+}
+
 
 PJ_DEF(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr)
Index: /pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h
===================================================================
--- /pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h	(revision 5532)
@@ -46,8 +46,12 @@
  * supported by a video device.
  *
- * Default: 64
+ * Default: 128 (for Android), 64 (for others)
  */
 #ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT
-#   define PJMEDIA_VID_DEV_INFO_FMT_CNT 64
+#   if defined(PJ_ANDROID) && PJ_ANDROID != 0
+#       define PJMEDIA_VID_DEV_INFO_FMT_CNT 128
+#   else
+#       define PJMEDIA_VID_DEV_INFO_FMT_CNT 64
+#   endif
 #endif
 
Index: /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c
===================================================================
--- /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c	(revision 5532)
@@ -672,38 +672,36 @@
 			      pj_ice_sess_cand *cand)
 {
-    pj_str_t input;
-    char *token, *host;
-    int af;
-    pj_str_t s;
+    pj_str_t token, delim, host;
+    int af, found_idx;    
     pj_status_t status = PJNATH_EICEINCANDSDP;
 
     pj_bzero(cand, sizeof(*cand));
-    pj_strdup_with_null(pool, &input, orig_input);
 
     PJ_UNUSED_ARG(obj_name);
 
     /* Foundation */
-    token = strtok(input.ptr, " ");
-    if (!token) {
+    delim = pj_str(" ");
+    found_idx = pj_strtok(orig_input, &delim, &token, 0);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE foundation in candidate"));
 	goto on_return;
     }
-    pj_strdup2(pool, &cand->foundation, token);
+    pj_strdup(pool, &cand->foundation, &token);
 
     /* Component ID */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE component ID in candidate"));
 	goto on_return;
     }
-    cand->comp_id = (pj_uint8_t) atoi(token);
+    cand->comp_id = (pj_uint8_t)pj_strtoul(&token);
 
     /* Transport */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE transport in candidate"));
 	goto on_return;
     }
-    if (pj_ansi_stricmp(token, "UDP") != 0) {
+    if (pj_stricmp2(&token, "UDP") != 0) {
 	TRACE__((obj_name, 
 		 "Expecting ICE UDP transport only in candidate"));
@@ -712,24 +710,24 @@
 
     /* Priority */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE priority in candidate"));
 	goto on_return;
     }
-    cand->prio = atoi(token);
+    cand->prio = pj_strtoul(&token);
 
     /* Host */
-    host = strtok(NULL, " ");
-    if (!host) {
+    found_idx = pj_strtok(orig_input, &delim, &host, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE host in candidate"));
 	goto on_return;
     }
     /* Detect address family */
-    if (pj_ansi_strchr(host, ':'))
+    if (pj_strchr(&host, ':'))
 	af = pj_AF_INET6();
     else
 	af = pj_AF_INET();
     /* Assign address */
-    if (pj_sockaddr_init(af, &cand->addr, pj_cstr(&s, host), 0)) {
+    if (pj_sockaddr_init(af, &cand->addr, &host, 0)) {
 	TRACE__((obj_name, "Invalid ICE candidate address"));
 	goto on_return;
@@ -737,18 +735,18 @@
 
     /* Port */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + host.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE port number in candidate"));
 	goto on_return;
     }
-    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)atoi(token));
+    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)pj_strtoul(&token));
 
     /* typ */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
 	goto on_return;
     }
-    if (pj_ansi_stricmp(token, "typ") != 0) {
+    if (pj_stricmp2(&token, "typ") != 0) {
 	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
 	goto on_return;
@@ -756,25 +754,25 @@
 
     /* candidate type */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen);
+    if (found_idx == orig_input->slen) {
 	TRACE__((obj_name, "Expecting ICE candidate type in candidate"));
 	goto on_return;
     }
 
-    if (pj_ansi_stricmp(token, "host") == 0) {
+    if (pj_stricmp2(&token, "host") == 0) {
 	cand->type = PJ_ICE_CAND_TYPE_HOST;
 
-    } else if (pj_ansi_stricmp(token, "srflx") == 0) {
+    } else if (pj_stricmp2(&token, "srflx") == 0) {
 	cand->type = PJ_ICE_CAND_TYPE_SRFLX;
 
-    } else if (pj_ansi_stricmp(token, "relay") == 0) {
+    } else if (pj_stricmp2(&token, "relay") == 0) {
 	cand->type = PJ_ICE_CAND_TYPE_RELAYED;
 
-    } else if (pj_ansi_stricmp(token, "prflx") == 0) {
+    } else if (pj_stricmp2(&token, "prflx") == 0) {
 	cand->type = PJ_ICE_CAND_TYPE_PRFLX;
 
     } else {
-	PJ_LOG(5,(obj_name, "Invalid ICE candidate type %s in candidate", 
-		  token));
+	PJ_LOG(5,(obj_name, "Invalid ICE candidate type %.*s in candidate", 
+		  token.slen, token.ptr));
 	goto on_return;
     }
@@ -1839,4 +1837,9 @@
     tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);
 
+    pj_perror(5, tp_ice->base.name, result, "ICE operation complete"
+	      " (op=%d%s)", op,
+	      (op==PJ_ICE_STRANS_OP_INIT? "/initialization" :
+	      (op==PJ_ICE_STRANS_OP_NEGOTIATION? "/negotiation":"")));
+
     /* Notify application */
     if (tp_ice->cb.on_ice_complete)
Index: /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c
===================================================================
--- /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c	(revision 5532)
@@ -1217,61 +1217,60 @@
 				     int *tag)
 {
-    pj_str_t input;
-    char *token;
-    pj_str_t tmp;
+    pj_str_t token, delim;
     pj_status_t status;
-    int itmp, token_len;
+    int itmp, found_idx;
 
     pj_bzero(crypto, sizeof(*crypto));
-    pj_strdup_with_null(pool, &input, &attr->value);
 
     /* Tag */
-    token = strtok(input.ptr, " ");
-    if (!token) {
+    delim = pj_str(" ");
+    found_idx = pj_strtok(&attr->value, &delim, &token, 0);
+    if (found_idx == attr->value.slen) {
 	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));
 	return PJMEDIA_SDP_EINATTR;
     }
-    token_len = pj_ansi_strlen(token);
 
     /* Tag must not use leading zeroes. */
-    if (token_len > 1 && *token == '0')
+    if (token.slen > 1 && *token.ptr == '0')
 	return PJMEDIA_SDP_EINATTR;
 
     /* Tag must be decimal, i.e: contains only digit '0'-'9'. */
-    for (itmp = 0; itmp < token_len; ++itmp)
-	if (!pj_isdigit(token[itmp]))
+    for (itmp = 0; itmp < token.slen; ++itmp)
+	if (!pj_isdigit(token.ptr[itmp]))
 	    return PJMEDIA_SDP_EINATTR;
 
     /* Get tag value. */
-    *tag = atoi(token);
+    *tag = pj_strtoul(&token);
 
     /* Crypto-suite */
-    token = strtok(NULL, " ");
-    if (!token) {
+    found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);
+    if (found_idx == attr->value.slen) {
 	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));
 	return PJMEDIA_SDP_EINATTR;
     }
-    crypto->name = pj_str(token);
+    crypto->name = token;
 
     /* Key method */
-    token = strtok(NULL, ":");
-    if (!token) {
+    delim = pj_str(": ");
+    found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);
+    if (found_idx == attr->value.slen) {
 	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));
 	return PJMEDIA_SDP_EINATTR;
     }
-    if (pj_ansi_stricmp(token, "inline")) {
-	PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!",
-	          token));
+    if (pj_stricmp2(&token, "inline")) {
+	PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%.*s' "
+	          "not supported!", token.slen, token.ptr));
 	return PJMEDIA_SDP_EINATTR;
     }
 
-    /* Key */
-    token = strtok(NULL, "| ");
-    if (!token) {
+    /* Key */    
+    delim = pj_str("| ");
+    found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen);
+    if (found_idx == attr->value.slen) {
 	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));
 	return PJMEDIA_SDP_EINATTR;
     }
-    tmp = pj_str(token);
-    if (PJ_BASE64_TO_BASE256_LEN(tmp.slen) > MAX_KEY_LEN) {
+    
+    if (PJ_BASE64_TO_BASE256_LEN(token.slen) > MAX_KEY_LEN) {
 	PJ_LOG(4,(THIS_FILE, "Key too long"));
 	return PJMEDIA_SRTP_EINKEYLEN;
@@ -1281,5 +1280,5 @@
     crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);
     itmp = MAX_KEY_LEN;
-    status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr,
+    status = pj_base64_decode(&token, (pj_uint8_t*)crypto->key.ptr,
 			      &itmp);
     if (status != PJ_SUCCESS) {
Index: /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c
===================================================================
--- /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c	(revision 5532)
@@ -823,5 +823,5 @@
     unsigned pkt_cnt = 0;
     pj_timestamp initial_time;
-    pj_timestamp null_ts ={0};
+    pj_timestamp null_ts ={{0}};
 
 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
Index: /pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_msg.h
===================================================================
--- /pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_msg.h	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_msg.h	(revision 5532)
@@ -324,4 +324,5 @@
     PJ_STUN_ATTR_XOR_RELAYED_ADDR   = 0x0016,/**< TURN XOR-RELAYED-ADDRESS  */
     PJ_STUN_ATTR_REQ_ADDR_TYPE	    = 0x0017,/**< REQUESTED-ADDRESS-TYPE    */
+    PJ_STUN_ATTR_REQ_ADDR_FAMILY    = 0x0017,/**< REQUESTED-ADDRESS-FAMILY  */
     PJ_STUN_ATTR_EVEN_PORT	    = 0x0018,/**< TURN EVEN-PORT	    */
     PJ_STUN_ATTR_REQ_TRANSPORT	    = 0x0019,/**< TURN REQUESTED-TRANSPORT  */
@@ -964,8 +965,9 @@
 
 /**
- * This describes the REQUESTED-ADDRESS-TYPE attribute.
- * The REQUESTED-ADDRESS-TYPE attribute is used by clients to request
+ * According to RFC 6156, this describes the REQUESTED-ADDRESS-FAMILY
+ * attribute (formerly known as REQUESTED-ADDRESS-TYPE in the draft).
+ * The REQUESTED-ADDRESS-FAMILY attribute is used by clients to request
  * the allocation of a specific address type from a server.  The
- * following is the format of the REQUESTED-ADDRESS-TYPE attribute.
+ * following is the format of the REQUESTED-ADDRESS-FAMILY attribute.
 
  \verbatim
Index: /pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c
===================================================================
--- /pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c	(revision 5532)
@@ -377,5 +377,5 @@
 	cand->status = PJ_EPENDING;
 	cand->local_pref = RELAY_PREF;
-	cand->transport_id = CREATE_TP_ID(TP_TURN, idx);
+	cand->transport_id = tp_id;
 	cand->comp_id = (pj_uint8_t) comp->comp_id;
     }
@@ -414,6 +414,7 @@
 
     PJ_LOG(4,(ice_st->obj_name,
-		  "Comp %d: TURN relay candidate waiting for allocation",
-		  comp->comp_id));
+		  "Comp %d/%d: TURN relay candidate (tpid=%d) "
+		  "waiting for allocation",
+		  comp->comp_id, comp->cand_cnt-1, cand->transport_id));
 
     return PJ_SUCCESS;
@@ -516,6 +517,7 @@
 
 	PJ_LOG(4,(ice_st->obj_name,
-		  "Comp %d: srflx candidate starts Binding discovery",
-		  comp->comp_id));
+		  "Comp %d: srflx candidate (tpid=%d) starts "
+		  "Binding discovery",
+		  comp->comp_id, cand->transport_id));
 
 	pj_log_push_indent();
@@ -623,7 +625,7 @@
 	    if (cand_duplicate) {
 		PJ_LOG(4, (ice_st->obj_name,
-		       "Comp %d: host candidate %s is a duplicate",
+		       "Comp %d: host candidate %s (tpid=%d) is a duplicate",
 		       comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
-		       sizeof(addrinfo), 3)));
+		       sizeof(addrinfo), 3), cand->transport_id));
 
 		pj_bzero(&cand->addr, sizeof(cand->addr));
@@ -638,7 +640,9 @@
 
 	    PJ_LOG(4,(ice_st->obj_name,
-		      "Comp %d: host candidate %s added",
-		      comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
-						      sizeof(addrinfo), 3)));
+		      "Comp %d/%d: host candidate %s (tpid=%d) added",
+		      comp->comp_id, comp->cand_cnt-1, 
+		      pj_sockaddr_print(&cand->addr, addrinfo,
+					sizeof(addrinfo), 3),
+					cand->transport_id));
 	}
     }
@@ -941,11 +945,20 @@
 	 * have not been created.
 	 */
-	if (!comp || comp->creating) return;
+	if (!comp || comp->creating) {
+	    PJ_LOG(5, (ice_st->obj_name, "ICE init update: creating comp %d",
+		       (comp?comp->comp_id:(i+1)) ));
+	    return;
+	}
 
 	for (j=0; j<comp->cand_cnt; ++j) {
 	    pj_ice_sess_cand *cand = &comp->cand_list[j];
 
-	    if (cand->status == PJ_EPENDING)
+	    if (cand->status == PJ_EPENDING) {
+		PJ_LOG(5, (ice_st->obj_name, "ICE init update: "
+			   "comp %d/%d[%s] is pending",
+			   comp->comp_id, j,
+			   pj_ice_get_cand_type_name(cand->type)));
 		return;
+	    }
 	}
     }
@@ -1957,5 +1970,5 @@
 	char ipaddr[PJ_INET6_ADDRSTRLEN+8];
 	pj_ice_sess_cand *cand = NULL;
-	unsigned i;
+	unsigned i, cand_idx = 0xFF;
 
 	comp->turn[tp_idx].err_cnt = 0;
@@ -1973,4 +1986,5 @@
 	    {
 		cand = &comp->cand_list[i];
+		cand_idx = i;
 		break;
 	    }
@@ -2008,6 +2022,7 @@
 
 	PJ_LOG(4,(comp->ice_st->obj_name,
-		  "Comp %d: TURN allocation complete, relay address is %s",
-		  comp->comp_id,
+		  "Comp %d/%d: TURN allocation (tpid=%d) complete, "
+		  "relay address is %s",
+		  comp->comp_id, cand_idx, cand->transport_id,
 		  pj_sockaddr_print(&rel_info.relay_addr, ipaddr,
 				     sizeof(ipaddr), 3)));
@@ -2020,5 +2035,5 @@
     {
 	pj_ice_sess_cand *cand = NULL;
-	unsigned i;
+	unsigned i, cand_idx = 0xFF;
 
 	/* DNS resolution or TURN transport creation/allocation
@@ -2040,4 +2055,5 @@
 	    {
 		cand = &comp->cand_list[i];
+		cand_idx = i;
 		break;
 	    }
@@ -2050,5 +2066,10 @@
 	 * to the list.
 	 */
-	if (cand) cand->status = PJ_ERESOLVE;
+	if (cand) {
+	    cand->status = PJ_ERESOLVE;
+	    PJ_LOG(4,(comp->ice_st->obj_name,
+		      "Comp %d/%d: TURN resolving (tpid=%d) failed",
+		      comp->comp_id, cand_idx, cand->transport_id));
+	}
 
 	sess_init_update(comp->ice_st);
Index: /pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c
===================================================================
--- /pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c	(revision 5532)
@@ -181,5 +181,5 @@
 
     addr_len = pj_sockaddr_get_len(server);
-    pj_bzero(&local, sizeof(pj_sockaddr));
+    pj_sockaddr_init(server->addr.sa_family, &local, NULL, 0);
     status = pj_sock_bind(sock, &local, addr_len);
     if (status != PJ_SUCCESS) {
@@ -281,6 +281,6 @@
      * Bind to any.
      */
-    pj_bzero(&sess->local_addr, sizeof(pj_sockaddr));
     addr_len = pj_sockaddr_get_len(server);
+    pj_sockaddr_init(server->addr.sa_family, &sess->local_addr, NULL, 0);
     status = pj_sock_bind(sess->sock, &sess->local_addr, addr_len);
     if (status != PJ_SUCCESS)
Index: /pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg.c
===================================================================
--- /pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg.c	(revision 5532)
@@ -344,6 +344,6 @@
     },
     {
-	/* PJ_STUN_ATTR_REQUESTED_ADDR_TYPE, */
-	"REQUESTED-ADDRESS-TYPE",
+	/* PJ_STUN_ATTR_REQUESTED_ADDR_FAMILY, */
+	"REQUESTED-ADDRESS-FAMILY",
 	&decode_uint_attr,
 	&encode_uint_attr,
Index: /pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c
===================================================================
--- /pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c	(revision 5532)
@@ -429,4 +429,12 @@
 	pj_grp_lock_release(turn_sock->grp_lock);
 	return status;
+    } else if (!turn_sock->sess) {
+	/* TURN session may have been destroyed here, i.e: when DNS resolution
+	 * completed synchronously and TURN allocation failed.
+	 */
+	PJ_LOG(4,(turn_sock->obj_name, "TURN session destroyed in setting "
+				       "TURN server"));
+	pj_grp_lock_release(turn_sock->grp_lock);
+	return PJ_EGONE;
     }
 
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java	(revision 5532)
@@ -139,4 +139,15 @@
 	    }
 	}
+
+        @Override
+        public void onCallVideoStart() {
+            MainActivity ma = ((MyHandler)ui_handler.get()).mTarget.get();
+            SurfaceView surfaceView = (SurfaceView)
+                ma.findViewById(R.id.surfaceViewIncomingCall);
+
+            WindowHandle wh = new WindowHandle();
+            wh.setWindow(surfaceView.getHolder().getSurface());
+            pjsua.setVideoWindow(wh);
+        }
     }
 
@@ -262,15 +273,19 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
     {
-	pjsua.setIncomingVideoRenderer(holder.getSurface());
+        WindowHandle wh = new WindowHandle();
+        wh.setWindow(holder.getSurface());
+        pjsua.setVideoWindow(wh);
     }
 
     public void surfaceCreated(SurfaceHolder holder)
     {
-	pjsua.setIncomingVideoRenderer(holder.getSurface());
+
     }
 
     public void surfaceDestroyed(SurfaceHolder holder)
     {
-	pjsua.setIncomingVideoRenderer(null);
+        WindowHandle wh = new WindowHandle();
+        wh.setWindow(null);
+        pjsua.setVideoWindow(wh);
     }
     
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i	(revision 5532)
@@ -15,8 +15,12 @@
 %feature("director") PjsuaAppCallback;
 
-/* Convert Surface object to ANativeWindow for setIncomingVideoRenderer() */
+/* Convert Surface object to ANativeWindow */
 %typemap(in) jobject surface {
     $1 = $input? (jobject)ANativeWindow_fromSurface(jenv, $input) : NULL;
 }
 
+%extend WindowHandle {
+    void setWindow(jobject surface) { $self->window = surface; }
+}
+
 %include "pjsua_app_callback.h"
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp	(revision 5532)
@@ -31,5 +31,14 @@
 static char **restart_argv;
 static pjsua_callback pjsua_cb_orig;
-static jobject callVideoSurface;
+static pjsua_vid_win_id winId = PJSUA_INVALID_ID;
+
+void setVideoWindow(const WindowHandle& win)
+{
+    pjmedia_vid_dev_hwnd vhwnd;
+   
+    vhwnd.info.window = win.window;
+    if (winId != PJSUA_INVALID_ID)
+    	pjsua_vid_win_set_win(winId, &vhwnd);
+}
 
 extern const char *pjsua_app_def_argv[];
@@ -58,11 +67,6 @@
 	    med_info->stream.vid.win_in != PJSUA_INVALID_ID)
 	{
-	    pjmedia_vid_dev_hwnd vhwnd;
-
-	    /* Setup renderer surface */
-	    pj_bzero(&vhwnd, sizeof(vhwnd));
-	    vhwnd.type = PJMEDIA_VID_DEV_HWND_TYPE_ANDROID;
-	    vhwnd.info.window = callVideoSurface;
-	    pjsua_vid_win_set_win(med_info->stream.vid.win_in, &vhwnd);
+	    winId = med_info->stream.vid.win_in;
+	    registeredCallbackObject->onCallVideoStart();
 	    break;
 	}
@@ -163,9 +167,3 @@
 }
 
-
-void setIncomingVideoRenderer(jobject surface)
-{
-    callVideoSurface = surface;
-}
-
 #endif
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h	(revision 5532)
@@ -20,6 +20,4 @@
 #define __PJSUA_APP_CALLBACK_H__
 
-#include <jni.h>
-
 class PjsuaAppCallback {
 public:
@@ -27,5 +25,12 @@
     virtual void onStarted(const char *msg) {}
     virtual void onStopped(int restart) {}
+    virtual void onCallVideoStart() {}
 };
+
+typedef struct WindowHandle {
+    void    	*window;
+} WindowHandle;
+
+void setVideoWindow(const WindowHandle& win);
 
 extern "C" {
@@ -34,5 +39,4 @@
 int pjsuaRestart();
 void setCallbackObject(PjsuaAppCallback* callback);
-void setIncomingVideoRenderer(jobject surface);
 }
 
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5532)
@@ -386,4 +386,15 @@
 	}
 
+	try {
+	    sipTpConfig.setPort(SIP_PORT+1);
+	    ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TLS,
+			       sipTpConfig);
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+
+        /* Set SIP port back to default for JSON saved config */
+        sipTpConfig.setPort(SIP_PORT);
+
 	/* Create accounts. */
 	for (int i = 0; i < accCfgs.size(); i++) {
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i	(revision 5532)
@@ -34,4 +34,8 @@
 
 typedef enum pj_ssl_sock_proto {PJ_SSL_SOCK_PROTO_DEFAULT = 0, PJ_SSL_SOCK_PROTO_SSL2 = 1 << 0, PJ_SSL_SOCK_PROTO_SSL3 = 1 << 1, PJ_SSL_SOCK_PROTO_TLS1 = 1 << 2, PJ_SSL_SOCK_PROTO_TLS1_1 = 1 << 3, PJ_SSL_SOCK_PROTO_TLS1_2 = 1 << 4, PJ_SSL_SOCK_PROTO_SSL23 = (1 << 16) - 1, PJ_SSL_SOCK_PROTO_DTLS1 = 1 << 16} pj_ssl_sock_proto;
+
+typedef enum pj_ssl_cert_name_type {PJ_SSL_CERT_NAME_UNKNOWN = 0, PJ_SSL_CERT_NAME_RFC822, PJ_SSL_CERT_NAME_DNS, PJ_SSL_CERT_NAME_URI, PJ_SSL_CERT_NAME_IP} pj_ssl_cert_name_type;
+
+typedef enum pj_ssl_cert_verify_flag_t {PJ_SSL_CERT_ESUCCESS = 0, PJ_SSL_CERT_EISSUER_NOT_FOUND = (1 << 0), PJ_SSL_CERT_EUNTRUSTED = (1 << 1), PJ_SSL_CERT_EVALIDITY_PERIOD = (1 << 2), PJ_SSL_CERT_EINVALID_FORMAT = (1 << 3), PJ_SSL_CERT_EINVALID_PURPOSE = (1 << 4), PJ_SSL_CERT_EISSUER_MISMATCH = (1 << 5), PJ_SSL_CERT_ECRL_FAILURE = (1 << 6), PJ_SSL_CERT_EREVOKED = (1 << 7), PJ_SSL_CERT_ECHAIN_TOO_LONG = (1 << 8), PJ_SSL_CERT_EIDENTITY_NOT_MATCH = (1 << 30), PJ_SSL_CERT_EUNKNOWN = (1 << 31)} pj_ssl_cert_verify_flag_t;
 
 typedef enum pj_stun_nat_type {PJ_STUN_NAT_TYPE_UNKNOWN, PJ_STUN_NAT_TYPE_ERR_UNKNOWN, PJ_STUN_NAT_TYPE_OPEN, PJ_STUN_NAT_TYPE_BLOCKED, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP, PJ_STUN_NAT_TYPE_FULL_CONE, PJ_STUN_NAT_TYPE_SYMMETRIC, PJ_STUN_NAT_TYPE_RESTRICTED, PJ_STUN_NAT_TYPE_PORT_RESTRICTED} pj_stun_nat_type;
Index: /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst
===================================================================
--- /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst	(revision 5532)
@@ -3,5 +3,5 @@
 pj/log.h			pj_log_decoration
 pj/sock_qos.h			pj_qos_type pj_qos_flag pj_qos_wmm_prio pj_qos_params
-pj/ssl_sock.h			pj_ssl_cipher pj_ssl_sock_proto
+pj/ssl_sock.h			pj_ssl_cipher pj_ssl_sock_proto pj_ssl_cert_name_type pj_ssl_cert_verify_flag_t
 
 pjnath/nat_detect.h          	pj_stun_nat_type
Index: /pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- /pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp	(revision 5532)
@@ -125,4 +125,149 @@
 
 /**
+ * SSL certificate type and name structure.
+ */
+struct SslCertName
+{
+    pj_ssl_cert_name_type  type;    	    /**< Name type		*/
+    string		   name;    	    /**< The name		*/
+};
+
+/**
+ * SSL certificate information.
+ */
+struct SslCertInfo
+{
+    unsigned		version;	    /**< Certificate version	*/
+    unsigned char	serialNo[20];	    /**< Serial number, array
+				         	 of octets, first index
+					 	 is MSB			*/
+    string		subjectCn;	    /**< Subject common name	*/
+    string		subjectInfo;	    /**< One line subject, fields
+					 	 are separated by slash, e.g:
+					 	 "CN=sample.org/OU=HRD" */
+
+    string		issuerCn;	    /**< Issuer common name	*/
+    string		issuerInfo;	    /**< One line subject, fields
+					 	 are separated by slash */
+
+    TimeVal		validityStart;	    /**< Validity start		*/
+    TimeVal		validityEnd;	    /**< Validity end		*/
+    bool		validityGmt;	    /**< Flag if validity 
+					 	 date/time use GMT	*/
+
+    vector<SslCertName> subjectAltName;     /**< Subject alternative
+					 	 name extension		*/
+
+    string 		raw;		    /**< Raw certificate in PEM
+    						 format, only available
+					 	 for remote certificate */
+
+public:
+    /**
+     * Constructor.
+     */
+    SslCertInfo();
+
+    /**
+     * Check if the info is set with empty values.
+     *
+     * @return      	True if the info is empty.
+     */
+    bool isEmpty() const;
+
+    /**
+     * Convert from pjsip
+     */
+    void fromPj(const pj_ssl_cert_info &info);
+    
+private:
+    bool empty;
+};
+
+/**
+ * TLS transport information.
+ */
+struct TlsInfo
+{
+    /**
+     * Describes whether secure socket connection is established, i.e: TLS/SSL 
+     * handshaking has been done successfully.
+     */
+    bool 		established;
+
+    /**
+     * Describes secure socket protocol being used, see #pj_ssl_sock_proto. 
+     * Use bitwise OR operation to combine the protocol type.
+     */
+    unsigned 		protocol;
+
+    /**
+     * Describes cipher suite being used, this will only be set when connection
+     * is established.
+     */
+    pj_ssl_cipher	cipher;
+
+    /**
+     * Describes cipher name being used, this will only be set when connection
+     * is established.
+     */
+    string		cipherName;
+
+    /**
+     * Describes local address.
+     */
+    SocketAddress 	localAddr;
+
+    /**
+     * Describes remote address.
+     */
+    SocketAddress 	remoteAddr;
+   
+    /**
+     * Describes active local certificate info. Use SslCertInfo.isEmpty()
+     * to check if the local cert info is available.
+     */
+    SslCertInfo 	localCertInfo;
+   
+    /**
+     * Describes active remote certificate info. Use SslCertInfo.isEmpty()
+     * to check if the remote cert info is available.
+     */
+    SslCertInfo 	remoteCertInfo;
+
+    /**
+     * Status of peer certificate verification.
+     */
+    unsigned		verifyStatus;
+
+    /**
+     * Error messages (if any) of peer certificate verification, based on
+     * the field verifyStatus above.
+     */
+    StringVector	verifyMsgs;
+
+public:
+    /**
+     * Constructor.
+     */
+    TlsInfo();
+
+    /**
+     * Check if the info is set with empty values.
+     *
+     * @return      	True if the info is empty.
+     */
+    bool isEmpty() const;
+
+    /**
+     * Convert from pjsip
+     */
+    void fromPj(const pjsip_tls_state_info &info);
+
+private:
+    bool empty;
+};
+
+/**
  * Parameter of Endpoint::onTransportState() callback.
  */
@@ -133,4 +278,9 @@
      */
     TransportHandle	hnd;
+    
+    /**
+     * The transport type.
+     */
+    string		type;
 
     /**
@@ -143,4 +293,10 @@
      */
     pj_status_t		lastError;
+    
+    /**
+     * TLS transport info, only used if transport type is TLS. Use 
+     * TlsInfo.isEmpty() to check if this info is available.
+     */
+    TlsInfo		tlsInfo;
 };
 
@@ -1030,4 +1186,19 @@
      */
     void transportClose(TransportId id) throw(Error);
+    
+    /**
+     * Start graceful shutdown procedure for this transport handle. After
+     * graceful shutdown has been initiated, no new reference can be
+     * obtained for the transport. However, existing objects that currently
+     * uses the transport may still use this transport to send and receive
+     * packets. After all objects release their reference to this transport,
+     * the transport will be destroyed immediately.
+     *
+     * Note: application normally uses this API after obtaining the handle
+     * from onTransportState() callback.
+     *
+     * @param tp		The transport.
+     */
+    void transportShutdown(TransportHandle tp) throw(Error);
 
     /*************************************************************************
Index: /pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c
===================================================================
--- /pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c	(revision 5532)
@@ -77,4 +77,5 @@
     int			is_closing;
     pj_bool_t		is_paused;
+    int			read_loop_spin;
 
     /* Group lock to be used by UDP transport and ioqueue key */
@@ -130,13 +131,15 @@
     pj_status_t status;
 
+    ++tp->read_loop_spin;
+
     /* Don't do anything if transport is closing. */
     if (tp->is_closing) {
 	tp->is_closing++;
-	return;
+	goto on_return;
     }
 
     /* Don't do anything if transport is being paused. */
     if (tp->is_paused)
-	return;
+	goto on_return;
 
     /*
@@ -228,5 +231,5 @@
 	 */
 	if (tp->is_paused)
-	    return;
+	    break;
 
 	/* Read next packet. */
@@ -244,4 +247,8 @@
 
 	} else if (status == PJ_EPENDING) {
+	    break;
+
+	} else if (status == PJ_ECANCELLED) {
+	    /* Socket is closing, quit loop */
 	    break;
 
@@ -277,4 +284,7 @@
 	}
     }
+
+on_return:
+    --tp->read_loop_spin;
 }
 
@@ -624,11 +634,14 @@
     	return PJ_SUCCESS;
 
-    /* Create group lock */
-    status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    pj_grp_lock_add_ref(tp->grp_lock);
-    pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, &udp_on_destroy);
+    /* Create group lock if not yet (don't need to do so on UDP restart) */
+    if (!tp->grp_lock) {
+	status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	pj_grp_lock_add_ref(tp->grp_lock);
+	pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp,
+				&udp_on_destroy);
+    }
     
     /* Register to ioqueue. */
@@ -1076,4 +1089,9 @@
     tp = (struct udp_transport*) transport;
 
+    /* Pause the transport first, so that any active read loop spin will
+     * quit as soon as possible.
+     */
+    tp->is_paused = PJ_TRUE;
+
     if (option & PJSIP_UDP_TRANSPORT_DESTROY_SOCKET) {
 	char addr_buf[PJ_INET6_ADDRSTRLEN];
@@ -1139,4 +1157,9 @@
     }
 
+    /* Make sure all udp_on_read_complete() loop spin are stopped */
+    do {
+	pj_thread_sleep(1);
+    } while (tp->read_loop_spin);
+
     /* Re-register new or existing socket to ioqueue. */
     status = register_to_ioqueue(tp);
Index: /pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- /pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5532)
@@ -1742,4 +1742,7 @@
         call->med_ch_mutex = NULL;
     }
+
+    PJ_PERROR(5,(THIS_FILE, status,
+		 "Call %d: media transport initialization complete", call_id));
 
     if (status != PJ_SUCCESS) {
Index: /pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- /pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp	(revision 5531)
+++ /pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp	(revision 5532)
@@ -45,4 +45,81 @@
 ///////////////////////////////////////////////////////////////////////////////
 
+TlsInfo::TlsInfo()
+	: empty(true)
+{
+}
+
+bool TlsInfo::isEmpty() const
+{
+    return empty;
+}
+
+void TlsInfo::fromPj(const pjsip_tls_state_info &info)
+{
+#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
+    pj_ssl_sock_info *ssock_info = info.ssl_sock_info;
+    char straddr[PJ_INET6_ADDRSTRLEN+10];
+    const char *verif_msgs[32];
+    unsigned verif_msg_cnt;
+    
+    empty	= false;
+    established = PJ2BOOL(ssock_info->established);
+    protocol 	= ssock_info->proto;
+    cipher 	= ssock_info->cipher;
+    cipherName	= pj_ssl_cipher_name(ssock_info->cipher);
+    pj_sockaddr_print(&ssock_info->local_addr, straddr, sizeof(straddr), 3);
+    localAddr 	= straddr;
+    pj_sockaddr_print(&ssock_info->remote_addr, straddr, sizeof(straddr),3);
+    remoteAddr 	= straddr;
+    verifyStatus = ssock_info->verify_status;
+    if (ssock_info->local_cert_info)
+        localCertInfo.fromPj(*ssock_info->local_cert_info);
+    if (ssock_info->remote_cert_info)
+        remoteCertInfo.fromPj(*ssock_info->remote_cert_info);
+    
+    /* Dump server TLS certificate verification result */
+    verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
+    pj_ssl_cert_get_verify_status_strings(ssock_info->verify_status,
+    				      	  verif_msgs, &verif_msg_cnt);
+    for (unsigned i = 0; i < verif_msg_cnt; ++i) {
+        verifyMsgs.push_back(verif_msgs[i]);
+    }
+#endif
+}
+
+SslCertInfo::SslCertInfo()
+	: empty(true)
+{
+}
+
+bool SslCertInfo::isEmpty() const
+{
+    return empty;
+}
+
+void SslCertInfo::fromPj(const pj_ssl_cert_info &info)
+{
+    empty 	= false;
+    version 	= info.version;
+    pj_memcpy(serialNo, info.serial_no, sizeof(info.serial_no));
+    subjectCn 	= pj2Str(info.subject.cn);
+    subjectInfo = pj2Str(info.subject.info);
+    issuerCn 	= pj2Str(info.issuer.cn);
+    issuerInfo 	= pj2Str(info.issuer.info);
+    validityStart.fromPj(info.validity.start);
+    validityEnd.fromPj(info.validity.end);
+    validityGmt = PJ2BOOL(info.validity.gmt);
+    raw 	= pj2Str(info.raw);
+
+    for (unsigned i = 0; i < info.subj_alt_name.cnt; i++) {
+    	SslCertName cname;
+    	cname.type = info.subj_alt_name.entry[i].type;
+    	cname.name = pj2Str(info.subj_alt_name.entry[i].name);
+    	subjectAltName.push_back(cname);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 UaConfig::UaConfig()
 : mainThreadOnly(false)
@@ -559,6 +636,17 @@
 
     prm.hnd = (TransportHandle)tp;
+    prm.type = tp->type_name;
     prm.state = state;
     prm.lastError = info ? info->status : PJ_SUCCESS;
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0
+    if (!pj_ansi_stricmp(tp->type_name, "tls") && info->ext_info &&
+	(state == PJSIP_TP_STATE_CONNECTED || 
+	 ((pjsip_tls_state_info*)info->ext_info)->
+			         ssl_sock_info->verify_status != PJ_SUCCESS))
+    {
+    	prm.tlsInfo.fromPj(*((pjsip_tls_state_info*)info->ext_info));
+    }
+#endif
 
     ep.onTransportState(prm);
@@ -1695,4 +1783,9 @@
 }
 
+void Endpoint::transportShutdown(TransportHandle tp) throw(Error)
+{
+    PJSUA2_CHECK_EXPR( pjsip_transport_shutdown((pjsip_transport *)tp) );
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /*
