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;
}
}
-void TunnelManager::processTunnelEvent(){
+void TunnelManager::processTunnelEvent(const Event &ev){
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
}
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
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() {
mAutoDetectStarted=true;
mCurrentUdpMirrorClient =mUdpMirrorClients.begin();
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
- lUdpMirrorClient.start(TunnelManager::UdpMirrorClientListener,(void*)this);
+ lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
}
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);
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;
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;
};
/**
* @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
**/
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);
/**