Index: pjproject/branches/1.0/pjlib/src/pj/ioqueue_symbian.cpp
===================================================================
--- pjproject/branches/1.0/pjlib/src/pj/ioqueue_symbian.cpp	(revision 2803)
+++ pjproject/branches/1.0/pjlib/src/pj/ioqueue_symbian.cpp	(revision 2804)
@@ -214,5 +214,14 @@
 	aAddress_.SetAddress(0);
 	aAddress_.SetPort(0);
-	sock_->Socket().Recv(aBufferPtr_, flags, iStatus);
+
+	if (sock_->IsDatagram()) {
+	    sock_->Socket().Recv(aBufferPtr_, flags, iStatus);
+	} else {
+	    // Using static like this is not pretty, but we don't need to use
+	    // the value anyway, hence doing it like this is probably most
+	    // optimal.
+	    static TSockXfrLength len;
+	    sock_->Socket().RecvOneOrMore(aBufferPtr_, flags, iStatus, len);
+	}
     }
 
@@ -278,4 +287,5 @@
 {
 	CPjSocket *pjNewSock = new CPjSocket(get_pj_socket()->GetAf(), 
+					     get_pj_socket()->GetSockType(),
 					     blank_sock_);
 	int addrlen = 0;
Index: pjproject/branches/1.0/pjlib/src/pj/os_symbian.h
===================================================================
--- pjproject/branches/1.0/pjlib/src/pj/os_symbian.h	(revision 2803)
+++ pjproject/branches/1.0/pjlib/src/pj/os_symbian.h	(revision 2804)
@@ -55,6 +55,7 @@
 
     // Construct CPjSocket
-    CPjSocket(int af, RSocket &sock)
-	: af_(af), sock_(sock), connected_(false), sockReader_(NULL)
+    CPjSocket(int af, int sock_type, RSocket &sock)
+	: af_(af), sock_(sock), sock_type_(sock_type), connected_(false), 
+	  sockReader_(NULL)
     { 
     }
@@ -87,4 +88,16 @@
     }
 
+    // Get socket type
+    int GetSockType() const
+    {
+	return sock_type_;
+    }
+    
+    // Returns true if socket is a datagram
+    bool IsDatagram() const
+    {
+	return sock_type_ == KSockDatagram;
+    }
+    
     // Get socket reader, if any.
     // May return NULL.
@@ -104,4 +117,6 @@
     RSocket	     sock_;	    // Must not be reference, or otherwise
 				    // it may point to local variable!
+    unsigned   	     sock_type_;
+    
     bool	     connected_;
     CPjSocketReader *sockReader_;
Index: pjproject/branches/1.0/pjlib/src/pj/sock_symbian.cpp
===================================================================
--- pjproject/branches/1.0/pjlib/src/pj/sock_symbian.cpp	(revision 2803)
+++ pjproject/branches/1.0/pjlib/src/pj/sock_symbian.cpp	(revision 2804)
@@ -126,11 +126,5 @@
 void CPjSocketReader::ConstructL(unsigned max_len)
 {
-    TProtocolDesc aProtocol;
-    TInt err;
-
-    err = sock_.Socket().Info(aProtocol);
-    User::LeaveIfError(err);
-
-    isDatagram_ = (aProtocol.iSockType == KSockDatagram);
+    isDatagram_ = sock_.IsDatagram();
 
     TUint8 *ptr = new TUint8[max_len];
@@ -518,5 +512,5 @@
 
     /* Wrap Symbian RSocket into PJLIB's CPjSocket, and return to caller */
-    CPjSocket *pjSock = new CPjSocket(af, rSock);
+    CPjSocket *pjSock = new CPjSocket(af, type, rSock);
     *p_sock = (pj_sock_t)pjSock;
 
@@ -734,5 +728,4 @@
 
     CPjSocket *pjSock = (CPjSocket*)sock;
-    RSocket &rSock = pjSock->Socket();
 
     if (pjSock->Reader()) {
@@ -758,5 +751,13 @@
     TPtr8 data((TUint8*)buf, (TInt)*len, (TInt)*len);
 
-    rSock.Recv(data, flags, reqStatus, recvLen);
+    if (pjSock->IsDatagram()) {
+	pjSock->Socket().Recv(data, flags, reqStatus);
+    } else {
+	// Using static like this is not pretty, but we don't need to use
+	// the value anyway, hence doing it like this is probably most
+	// optimal.
+	static TSockXfrLength len;
+	pjSock->Socket().RecvOneOrMore(data, flags, reqStatus, len);
+    }
     User::WaitForRequest(reqStatus);
 
@@ -998,5 +999,6 @@
 
     // Create PJ socket
-    CPjSocket *newPjSock = new CPjSocket(pjSock->GetAf(), newSock);
+    CPjSocket *newPjSock = new CPjSocket(pjSock->GetAf(), pjSock->GetSockType(),
+					 newSock);
     newPjSock->SetConnected(true);
 
Index: pjproject/branches/1.0/pjlib/src/pjlib-test/activesock.c
===================================================================
--- pjproject/branches/1.0/pjlib/src/pjlib-test/activesock.c	(revision 2803)
+++ pjproject/branches/1.0/pjlib/src/pjlib-test/activesock.c	(revision 2804)
@@ -213,5 +213,9 @@
 	for (i=0; i<10 && last_rx1 == srv1->rx_cnt && last_rx2 == srv2->rx_cnt; ++i) {
 	    pj_time_val delay = {0, 10};
+#ifdef PJ_SYMBIAN
+	    pj_symbianos_poll(-1, 100);
+#else
 	    pj_ioqueue_poll(ioqueue, &delay);
+#endif
 	}
 
@@ -404,16 +408,32 @@
 	if (status == PJ_EPENDING) {
 	    do {
+#if PJ_SYMBIAN
+		pj_symbianos_poll(-1, -1);
+#else
 		pj_ioqueue_poll(ioqueue, NULL);
+#endif
 	    } while (!state2->sent);
-	} else if (status != PJ_SUCCESS) {
-		PJ_LOG(1,("", "   err: send status=%d", status));
-	    status = -180;
-	    break;
-	} else if (status == PJ_SUCCESS) {
-	    if (len != sizeof(*pkt)) {
-		PJ_LOG(1,("", "   err: shouldn't report partial sent"));
-		status = -190;
-		break;
-	    }
+	} else {
+#if PJ_SYMBIAN
+		/* The Symbian socket always returns PJ_SUCCESS for TCP send,
+		 * eventhough the remote end hasn't received the data yet.
+		 * If we continue sending, eventually send() will block,
+		 * possibly because the send buffer is full. So we need to
+		 * poll the ioqueue periodically, to let receiver gets the 
+		 * data.
+		 */
+		pj_symbianos_poll(-1, 0);
+#endif
+		if (status != PJ_SUCCESS) {
+		    PJ_LOG(1,("", "   err: send status=%d", status));
+		    status = -180;
+		    break;
+		} else if (status == PJ_SUCCESS) {
+		    if (len != sizeof(*pkt)) {
+			PJ_LOG(1,("", "   err: shouldn't report partial sent"));
+			status = -190;
+			break;
+		    }
+		}
 	}
     }
@@ -421,7 +441,12 @@
     /* Wait until everything has been sent/received */
     if (state1->next_recv_seq < COUNT) {
+#ifdef PJ_SYMBIAN
+	while (pj_symbianos_poll(-1, 1000) == PJ_TRUE)
+	    ;
+#else
 	pj_time_val delay = {0, 100};
 	while (pj_ioqueue_poll(ioqueue, &delay) > 0)
 	    ;
+#endif
     }
 
Index: pjproject/branches/1.0/pjsip-apps/src/symbian_ua/ua.cpp
===================================================================
--- pjproject/branches/1.0/pjsip-apps/src/symbian_ua/ua.cpp	(revision 2803)
+++ pjproject/branches/1.0/pjsip-apps/src/symbian_ua/ua.cpp	(revision 2804)
@@ -50,4 +50,8 @@
 //#define SIP_PROXY	"<sip:192.168.0.8;lr>"
 
+//
+// Set to 1 if TCP is desired (experimental)
+//
+#define ENABLE_SIP_TCP	0
 
 //
@@ -380,9 +384,21 @@
     status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &tid);
     if (status != PJ_SUCCESS) {
-	    pjsua_perror(THIS_FILE, "Error creating transport", status);
+	    pjsua_perror(THIS_FILE, "Error creating UDP transport", status);
 	    pjsua_destroy();
 	    return status;
     }
 
+    /* Add TCP transport */
+#if ENABLE_SIP_TCP
+    pjsua_transport_config_default(&tcfg);
+    tcfg.port = SIP_PORT;
+    status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &tcfg, &tid);
+    if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Error creating TCP transport", status);
+	    pjsua_destroy();
+	    return status;
+    }
+#endif
+    
     /* Add account for the transport */
     pjsua_acc_add_local(tid, PJ_TRUE, &g_acc_id);
Index: pjproject/branches/1.0/pjsip/src/pjsip/sip_transport_tcp.c
===================================================================
--- pjproject/branches/1.0/pjsip/src/pjsip/sip_transport_tcp.c	(revision 2803)
+++ pjproject/branches/1.0/pjsip/src/pjsip/sip_transport_tcp.c	(revision 2804)
@@ -806,5 +806,5 @@
 					 sizeof(pj_sockaddr_in));
     if (status == PJ_SUCCESS) {
-	tcp->has_pending_connect = PJ_FALSE;
+	on_connect_complete(tcp->asock, PJ_SUCCESS);
     } else if (status != PJ_EPENDING) {
 	tcp_destroy(&tcp->base, status);
@@ -812,25 +812,25 @@
     }
 
-    /* Update (again) local address, just in case local address currently
-     * set is different now that asynchronous connect() is started.
-     */
-    addr_len = sizeof(pj_sockaddr_in);
-    if (pj_sock_getsockname(sock, &local_addr, &addr_len)==PJ_SUCCESS) {
-	pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tcp->base.local_addr;
-
-	/* Some systems (like old Win32 perhaps) may not set local address
-	 * properly before socket is fully connected.
+    if (tcp->has_pending_connect) {
+	/* Update (again) local address, just in case local address currently
+	 * set is different now that asynchronous connect() is started.
 	 */
-	if (tp_addr->sin_addr.s_addr != local_addr.sin_addr.s_addr &&
-	    local_addr.sin_addr.s_addr != 0) 
-	{
-	    tp_addr->sin_addr.s_addr = local_addr.sin_addr.s_addr;
-	    tp_addr->sin_port = local_addr.sin_port;
-	    sockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name,
-				  &local_addr);
+	addr_len = sizeof(pj_sockaddr_in);
+	if (pj_sock_getsockname(sock, &local_addr, &addr_len)==PJ_SUCCESS) {
+	    pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tcp->base.local_addr;
+
+	    /* Some systems (like old Win32 perhaps) may not set local address
+	     * properly before socket is fully connected.
+	     */
+	    if (tp_addr->sin_addr.s_addr != local_addr.sin_addr.s_addr &&
+		local_addr.sin_addr.s_addr != 0) 
+	    {
+		tp_addr->sin_addr.s_addr = local_addr.sin_addr.s_addr;
+		tp_addr->sin_port = local_addr.sin_port;
+		sockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name,
+				      &local_addr);
+	    }
 	}
-    }
-
-    if (tcp->has_pending_connect) {
+	
 	PJ_LOG(4,(tcp->base.obj_name, 
 		  "TCP transport %.*s:%d is connecting to %.*s:%d...",
