summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2009-03-02 15:48:45 +0000
committerNanang Izzuddin <nanang@teluu.com>2009-03-02 15:48:45 +0000
commitc205201320f80d9e25e554566da5b7f11203f871 (patch)
tree9c36ccb99099beae87670633c72e63358c95df80 /pjlib
parent33e9dc9f2613a86b0fcfea7d669d1b83934d45fd (diff)
Ticket #732:
- Added new Symbian specific API in PJLIB, pj_symbianos_set_connection_status(), to let PJLIB knows the connection status. - Added connection status checks before Symbian socket operations. - Added loop limiter in Symbian busy_sleep() to avoid the possibility of infinite loop. - Added sample of connection monitor in Symbian sample application (ua.cpp). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2481 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/os.h12
-rw-r--r--pjlib/src/pj/addr_resolv_symbian.cpp3
-rw-r--r--pjlib/src/pj/ioqueue_symbian.cpp9
-rw-r--r--pjlib/src/pj/os_core_symbian.cpp31
-rw-r--r--pjlib/src/pj/os_symbian.h28
-rw-r--r--pjlib/src/pj/sock_symbian.cpp21
6 files changed, 95 insertions, 9 deletions
diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h
index 0bd18638..4a5a77f8 100644
--- a/pjlib/include/pj/os.h
+++ b/pjlib/include/pj/os.h
@@ -394,6 +394,18 @@ typedef struct pj_symbianos_params
*/
PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
+/**
+ * Notify PJLIB that the access point connection has been down or unusable
+ * and PJLIB should not try to access the Symbian socket API (especially ones
+ * that send packets). Sending packet when RConnection is reconnected to
+ * different access point may cause the WaitForRequest() for the function to
+ * block indefinitely.
+ *
+ * @param up If set to PJ_FALSE it will cause PJLIB to not try
+ * to access socket API, and error will be returned
+ * immediately instead.
+ */
+PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
/**
* @}
diff --git a/pjlib/src/pj/addr_resolv_symbian.cpp b/pjlib/src/pj/addr_resolv_symbian.cpp
index cfd8aa5d..fbca1085 100644
--- a/pjlib/src/pj/addr_resolv_symbian.cpp
+++ b/pjlib/src/pj/addr_resolv_symbian.cpp
@@ -71,6 +71,9 @@ static pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name,
PJ_ASSERT_RETURN(name && count && ai, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
// Get resolver for the specified address family
RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(af);
diff --git a/pjlib/src/pj/ioqueue_symbian.cpp b/pjlib/src/pj/ioqueue_symbian.cpp
index ba4092b9..ee6d7e0d 100644
--- a/pjlib/src/pj/ioqueue_symbian.cpp
+++ b/pjlib/src/pj/ioqueue_symbian.cpp
@@ -635,6 +635,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
TInetAddr inetAddr;
TRequestStatus reqStatus;
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
// Convert address
status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen,
inetAddr);
@@ -747,6 +750,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
// Forcing pending operation is not supported.
PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
// Clear flag
flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;
@@ -785,6 +791,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
// Forcing pending operation is not supported.
PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
// Convert address
status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen,
inetAddr);
diff --git a/pjlib/src/pj/os_core_symbian.cpp b/pjlib/src/pj/os_core_symbian.cpp
index 5fbf3d47..983ce88a 100644
--- a/pjlib/src/pj/os_core_symbian.cpp
+++ b/pjlib/src/pj/os_core_symbian.cpp
@@ -151,7 +151,8 @@ TInt CPjTimeoutTimer::RunError(TInt aError)
//
PjSymbianOS::PjSymbianOS()
-: isSocketServInitialized_(false), isResolverInitialized_(false),
+: isConnectionUp_(false),
+ isSocketServInitialized_(false), isResolverInitialized_(false),
console_(NULL), selectTimeoutTimer_(NULL),
appSocketServ_(NULL), appConnection_(NULL), appHostResolver_(NULL),
appHostResolver6_(NULL)
@@ -229,6 +230,8 @@ TInt PjSymbianOS::Initialize()
isResolverInitialized_ = true;
}
+ isConnectionUp_ = true;
+
return KErrNone;
on_error:
@@ -239,6 +242,8 @@ on_error:
// Shutdown
void PjSymbianOS::Shutdown()
{
+ isConnectionUp_ = false;
+
if (isResolverInitialized_) {
hostResolver_.Close();
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0
@@ -252,15 +257,16 @@ void PjSymbianOS::Shutdown()
isSocketServInitialized_ = false;
}
- if (console_) {
- delete console_;
- console_ = NULL;
- }
+ delete console_;
+ console_ = NULL;
- if (selectTimeoutTimer_) {
- delete selectTimeoutTimer_;
- selectTimeoutTimer_ = NULL;
- }
+ delete selectTimeoutTimer_;
+ selectTimeoutTimer_ = NULL;
+
+ appSocketServ_ = NULL;
+ appConnection_ = NULL;
+ appHostResolver_ = NULL;
+ appHostResolver6_ = NULL;
}
// Convert to Unicode
@@ -306,6 +312,13 @@ PJ_DEF(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm)
}
+/* Set connection status */
+PJ_DEF(void) pj_symbianos_set_connection_status(pj_bool_t up)
+{
+ PjSymbianOS::Instance()->SetConnectionStatus(up != 0);
+}
+
+
/*
* pj_init(void).
* Init PJLIB!
diff --git a/pjlib/src/pj/os_symbian.h b/pjlib/src/pj/os_symbian.h
index 74ae7f0c..3497e7af 100644
--- a/pjlib/src/pj/os_symbian.h
+++ b/pjlib/src/pj/os_symbian.h
@@ -313,6 +313,21 @@ public:
}
}
+ //
+ // Return true if the access point connection is up
+ //
+ bool IsConnectionUp() const
+ {
+ return isConnectionUp_;
+ }
+
+ //
+ // Set access point connection status
+ //
+ void SetConnectionStatus(bool up)
+ {
+ isConnectionUp_ = up;
+ }
//
// Unicode Converter
@@ -353,6 +368,8 @@ public:
}
private:
+ bool isConnectionUp_;
+
bool isSocketServInitialized_;
RSocketServ socketServ_;
@@ -374,6 +391,17 @@ private:
PjSymbianOS();
};
+// This macro is used to check the access point connection status and return
+// failure if the AP connection is down or unusable. See the documentation
+// of pj_symbianos_set_connection_status() for more info
+#define PJ_SYMBIAN_CHECK_CONNECTION() \
+ PJ_SYMBIAN_CHECK_CONNECTION2(PJ_ECANCELLED)
+
+#define PJ_SYMBIAN_CHECK_CONNECTION2(retval) \
+ do { \
+ if (!PjSymbianOS::Instance()->IsConnectionUp()) \
+ return retval; \
+ } while (0);
#endif /* __OS_SYMBIAN_H__ */
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index a1bd0a30..a0ca80e0 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -463,6 +463,9 @@ PJ_DEF(const pj_str_t*) pj_gethostname(void)
TRequestStatus reqStatus;
THostName tmpName;
+ // Return empty hostname if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION2(&hostname);
+
resv.GetHostName(tmpName, reqStatus);
User::WaitForRequest(reqStatus);
@@ -488,6 +491,9 @@ PJ_DEF(pj_status_t) pj_sock_socket(int af,
/* Sanity checks. */
PJ_ASSERT_RETURN(p_sock!=NULL, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
/* Set proto if none is specified. */
if (proto == 0) {
if (type == pj_SOCK_STREAM())
@@ -642,6 +648,9 @@ PJ_DEF(pj_status_t) pj_sock_send(pj_sock_t sock,
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
CPjSocket *pjSock = (CPjSocket*)sock;
RSocket &rSock = pjSock->Socket();
@@ -678,6 +687,9 @@ PJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
CPjSocket *pjSock = (CPjSocket*)sock;
RSocket &rSock = pjSock->Socket();
@@ -717,6 +729,9 @@ PJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,
PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);
PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
CPjSocket *pjSock = (CPjSocket*)sock;
RSocket &rSock = pjSock->Socket();
@@ -771,6 +786,9 @@ PJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,
PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);
PJ_ASSERT_RETURN(*fromlen >= (int)sizeof(pj_sockaddr_in), PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
CPjSocket *pjSock = (CPjSocket*)sock;
RSocket &rSock = pjSock->Socket();
@@ -868,6 +886,9 @@ PJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock,
PJ_ASSERT_RETURN(((pj_sockaddr*)addr)->addr.sa_family == PJ_AF_INET,
PJ_EINVAL);
+ // Return failure if access point is marked as down by app.
+ PJ_SYMBIAN_CHECK_CONNECTION();
+
CPjSocket *pjSock = (CPjSocket*)sock;
RSocket &rSock = pjSock->Socket();