set processing of tunnel udp mirror callback on main thread.

This commit is contained in:
Simon Morlat 2012-09-17 15:57:11 +02:00
parent f278975609
commit b70085becb
3 changed files with 91 additions and 27 deletions

View file

@ -212,7 +212,6 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :TunnelClientController()
mExosipTransport.recvfrom=eXosipRecvfrom;
mExosipTransport.sendto=eXosipSendto;
mExosipTransport.select=eXosipSelect;
mStateChanged=false;
linphone_core_add_iterate_hook(mCore,(LinphoneCoreIterateHook)sOnIterate,this);
mTransportFactories.audio_rtcp_func=sCreateRtpTransport;
mTransportFactories.audio_rtcp_func_data=this;
@ -242,7 +241,7 @@ void TunnelManager::stopClient(){
}
}
void TunnelManager::processTunnelEvent(){
void TunnelManager::processTunnelEvent(const Event &ev){
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
@ -325,15 +324,31 @@ void TunnelManager::enable(bool isEnable) {
}
void TunnelManager::tunnelCallback(bool connected, TunnelManager *zis){
zis->mStateChanged=true;
Event ev;
ev.mType=TunnelEvent;
ev.mData.mConnected=connected;
zis->postEvent(ev);
}
void TunnelManager::onIterate(){
mMutex.lock();
while(!mEvq.empty()){
Event ev=mEvq.front();
mEvq.pop();
mMutex.unlock();
if (ev.mType==TunnelEvent)
processTunnelEvent(ev);
else if (ev.mType==UdpMirrorClientEvent){
processUdpMirrorEvent(ev);
}
mMutex.lock();
}
mMutex.unlock();
}
/*invoked from linphone_core_iterate() */
void TunnelManager::sOnIterate(TunnelManager *zis){
if (zis->mStateChanged){
zis->mStateChanged=false;
zis->processTunnelEvent();
}
zis->onIterate();
}
#ifdef ANDROID
@ -374,26 +389,39 @@ void TunnelManager::enableLogs(bool isEnabled,LogHandler logHandler) {
bool TunnelManager::isEnabled() {
return mEnabled;
}
void TunnelManager::UdpMirrorClientListener(bool isUdpAvailable, void* data) {
TunnelManager* thiz = (TunnelManager*)data;
if (isUdpAvailable) {
void TunnelManager::processUdpMirrorEvent(const Event &ev){
if (ev.mData.mHaveUdp) {
LOGI("Tunnel is not required, disabling");
thiz->enable(false);
thiz->mAutoDetectStarted = false;
enable(false);
mAutoDetectStarted = false;
} else {
if (++thiz->mCurrentUdpMirrorClient !=thiz->mUdpMirrorClients.end()) {
//1 enable tunnable but also try backup server
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
// enable tunnel but also try backup server
LOGI("Tunnel is required, enabling; Trying backup udp mirror");
UdpMirrorClient &lUdpMirrorClient=*thiz->mCurrentUdpMirrorClient;
lUdpMirrorClient.start(TunnelManager::UdpMirrorClientListener,(void*)thiz);
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
} else {
LOGI("Tunnel is required, enabling; no backup udp mirror available");
thiz->mAutoDetectStarted = false;
mAutoDetectStarted = false;
}
thiz->enable(true);
enable(true);
}
return;
}
void TunnelManager::postEvent(const Event &ev){
mMutex.lock();
mEvq.push(ev);
mMutex.unlock();
}
void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) {
TunnelManager* thiz = (TunnelManager*)data;
Event ev;
ev.mType=UdpMirrorClientEvent;
ev.mData.mHaveUdp=isUdpAvailable;
thiz->postEvent(ev);
}
void TunnelManager::autoDetect() {
@ -409,7 +437,7 @@ void TunnelManager::autoDetect() {
mAutoDetectStarted=true;
mCurrentUdpMirrorClient =mUdpMirrorClients.begin();
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
lUdpMirrorClient.start(TunnelManager::UdpMirrorClientListener,(void*)this);
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
}

View file

@ -130,9 +130,21 @@ class UdpMirrorClient;
LinphoneCore *getLinphoneCore();
virtual void setHttpProxy(const char *host,int port, const char *username, const char *passwd);
private:
enum EventType{
UdpMirrorClientEvent,
TunnelEvent,
};
struct Event{
EventType mType;
union EventData{
bool mConnected;
bool mHaveUdp;
}mData;
};
typedef std::list<UdpMirrorClient> UdpMirrorClientList;
virtual bool isStarted();
virtual bool isReady() const;
void onIterate();
static int customSendto(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen);
static int customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen);
static int eXosipSendto(int fd,const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen,void* userdata);
@ -140,9 +152,11 @@ class UdpMirrorClient;
static int eXosipSelect(int nfds, fd_set *s1, fd_set *s2, fd_set *s3, struct timeval *tv,void* userdata);
static void tunnelCallback(bool connected, TunnelManager *zis);
static void sOnIterate(TunnelManager *zis);
static void UdpMirrorClientListener(bool result, void* data);
static void sUdpMirrorClientCallback(bool result, void* data);
void waitUnRegistration();
void processTunnelEvent();
void processTunnelEvent(const Event &ev);
void processUdpMirrorEvent(const Event &ev);
void postEvent(const Event &ev);
LinphoneCore* mCore;
LCSipTransports mRegularTransport;
TunnelSocket *mSipSocket;
@ -150,19 +164,20 @@ class UdpMirrorClient;
StateCallback mCallback;
void * mCallbackData;
bool mEnabled;
bool mStateChanged;
std::queue<Event> mEvq;
std::list <ServerAddr> mServerAddrs;
UdpMirrorClientList mUdpMirrorClients;
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
TunnelClient* mTunnelClient;
void stopClient();
Mutex mMutex;
static Mutex sMutex;
bool mAutoDetectStarted;
LinphoneRtpTransportFactories mTransportFactories;
std::string mHttpUserName;
std::string mHttpPasswd;
std::string mHttpProxyHost;
int mHttpProxyPort;
int mHttpProxyPort;
};
/**

View file

@ -62,10 +62,10 @@ void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int po
* @param tunnel object
* @param host tunnel server ip address
* @param port tunnel server tls port, recommended value is 443
* @param remote_udp_mirror remote port on the tunnel server side used to test udp reachability
* @param remote_udp_mirror_port remote port on the tunnel server side used to test udp reachability
* @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms.
*/
void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror, int delay);
void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror_port, int delay);
/**
* @param tunnel object
* returns a string of space separated list of host:port of tunnel server addresses
@ -98,16 +98,37 @@ bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel);
**/
void linphone_tunnel_reconnect(LinphoneTunnel *tunnel);
/**
* Start tunnel need detection.
* @param tunnel object
* In auto detect mode, the tunnel manager try to establish a real time rtp cummunication with the tunnel server on specified port.
*<br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp commmunication is feasible, tunnel mode is turned on.
*<br> Call this method each time to run the auto detection algorithm
*/
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
/**
* Set an optional http proxy to go through when connecting to tunnel server.
* @param tunnel LinphoneTunnel object
* @param host Http proxy host.
* @param port http proxy port.
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
* @param password optional http proxy password. Use NULL if not needed.
**/
void linphone_tunnel_set_http_proxy(LinphoneTunnel *tunnel, const char *host, int port, const char* username,const char* passwd);
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd);
/**
* Retrieve optional http proxy configuration previously set with linphone_tunnel_set_http_proxy().
* @param tunnel LinphoneTunnel object
* @param host Http proxy host.
* @param port http proxy port.
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
* @param password optional http proxy password. Use NULL if not needed.
**/
void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int *port, const char **username, const char **passwd);
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd);
void linphone_tunnel_enable_logs(LinphoneTunnel *tunnel, bool_t enabled);
/**