diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2009-03-02 15:48:45 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2009-03-02 15:48:45 +0000 |
commit | c205201320f80d9e25e554566da5b7f11203f871 (patch) | |
tree | 9c36ccb99099beae87670633c72e63358c95df80 /pjlib | |
parent | 33e9dc9f2613a86b0fcfea7d669d1b83934d45fd (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.h | 12 | ||||
-rw-r--r-- | pjlib/src/pj/addr_resolv_symbian.cpp | 3 | ||||
-rw-r--r-- | pjlib/src/pj/ioqueue_symbian.cpp | 9 | ||||
-rw-r--r-- | pjlib/src/pj/os_core_symbian.cpp | 31 | ||||
-rw-r--r-- | pjlib/src/pj/os_symbian.h | 28 | ||||
-rw-r--r-- | pjlib/src/pj/sock_symbian.cpp | 21 |
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(); |