- libavcodec (ffmpeg)
- libswscale (part of ffmpeg too) for better scaling performance
- theora (optional)
+ + if you want uPnP support:
+ - libupnp
with their corresponding -dev or -devel package if you don't use source packages.
lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
lc->sip_conf.register_only_when_network_is_up=
lp_config_get_int(lc->config,"sip","register_only_when_network_is_up",1);
+ lc->sip_conf.register_only_when_upnp_is_ok=
+ lp_config_get_int(lc->config,"sip","register_only_when_upnp_is_ok",1);
lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1);
lc->sip_conf.auto_net_state_mon=lp_config_get_int(lc->config,"sip","auto_net_state_mon",1);
lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
return lc->net_conf.stun_server;
}
+bool_t linphone_core_upnp_available(const LinphoneCore *lc){
+#ifdef BUILD_UPNP
+ return TRUE;
+#else
+ return FALSE;
+#endif //BUILD_UPNP
+}
+
+LinphoneUpnpState linphone_core_get_upnp_state(const LinphoneCore *lc){
+#ifdef BUILD_UPNP
+ return linphone_upnp_context_get_state(lc->upnp);
+#else
+ return LinphoneUpnpStateNotAvailable;
+#endif //BUILD_UPNP
+}
+
+const char * linphone_core_get_upnp_external_ipaddress(const LinphoneCore *lc){
+#ifdef BUILD_UPNP
+ return linphone_upnp_context_get_external_ipaddress(lc->upnp);
+#else
+ return NULL;
+#endif //BUILD_UPNP
+}
+
+
const char * linphone_core_get_relay_addr(const LinphoneCore *lc){
return lc->net_conf.relay;
}
lp_config_set_int(lc->config,"sip","use_rfc2833",config->use_rfc2833);
lp_config_set_int(lc->config,"sip","use_ipv6",config->ipv6_enabled);
lp_config_set_int(lc->config,"sip","register_only_when_network_is_up",config->register_only_when_network_is_up);
-
+ lp_config_set_int(lc->config,"sip","register_only_when_upnp_is_ok",config->register_only_when_upnp_is_ok);
const char * linphone_core_get_stun_server(const LinphoneCore *lc);
+/**
+ * @ingroup network_parameters
+ * Return the availability of uPnP.
+ *
+ * @param lc #LinphoneCore
+ * @return true if uPnP is available otherwise return false.
+ */
+bool_t linphone_core_upnp_available(const LinphoneCore *lc);
+
+/**
+ * @ingroup network_parameters
+ * Return the internal state of uPnP.
+ *
+ * @param lc #LinphoneCore
+ * @return an LinphoneUpnpState.
+ */
+LinphoneUpnpState linphone_core_get_upnp_state(const LinphoneCore *lc);
+
+/**
+ * @ingroup network_parameters
+ * Return the external ip address of router.
+ * In some cases the uPnP can have an external ip address but not a usable uPnP
+ * (state different of Ok).
+ *
+ * @param lc #LinphoneCore
+ * @return a null terminated string containing the external ip address. If the
+ * the external ip address is not available return null.
+ */
+const char * linphone_core_get_upnp_external_ipaddress(const LinphoneCore *lc);
+
void linphone_core_set_nat_address(LinphoneCore *lc, const char *addr);
const char *linphone_core_get_nat_address(const LinphoneCore *lc);
return (jlong) linphone_core_get_config((LinphoneCore *)lc);
}
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_upnpAvailable(JNIEnv *env, jobject thiz, jlong lc) {
+ return (jboolean) linphone_core_upnp_available((LinphoneCore *)lc);
+}
+
+extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getUpnpState(JNIEnv *env, jobject thiz, jlong lc) {
+ return (jint) linphone_core_get_upnp_state((LinphoneCore *)lc);
+}
+
+extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getUpnpExternalIpaddress(JNIEnv *env, jobject thiz, jlong lc) {
+ jstring jvalue = env->NewStringUTF(linphone_core_get_upnp_external_ipaddress((LinphoneCore *)lc));
+ return jvalue;
+}
+
extern "C" jlong Java_org_linphone_core_LpConfigImpl_newLpConfigImpl(JNIEnv *env, jobject thiz, jstring file) {
const char *cfile = env->GetStringUTFChars(file, NULL);
LpConfig *lp = lp_config_new(cfile);
bool_t ipv6_enabled;
bool_t sdp_200_ack;
bool_t register_only_when_network_is_up;
+ bool_t register_only_when_upnp_is_ok;
bool_t ping_with_options;
bool_t auto_net_state_mon;
bool_t tcp_tls_keepalive;
if (cfg->type && cfg->ssctx==NULL){
linphone_proxy_config_activate_sip_setup(cfg);
}
- if (!lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
+ if ((!lc->sip_conf.register_only_when_network_is_up || lc->network_reachable) &&
+ (!lc->sip_conf.register_only_when_upnp_is_ok || linphone_core_get_upnp_state(lc) == LinphoneUpnpStateOk))
linphone_proxy_config_register(cfg);
if (cfg->publish && cfg->publish_op==NULL){
linphone_proxy_config_send_publish(cfg,lc->presence_mode);
old_state = lupnp->state;
switch(event) {
+ case UPNP_IGD_DEVICE_ADDED:
+ case UPNP_IGD_DEVICE_REMOVED:
case UPNP_IGD_EXTERNAL_IPADDRESS_CHANGED:
case UPNP_IGD_NAT_ENABLED_CHANGED:
case UPNP_IGD_CONNECTION_STATUS_CHANGED:
/* Send port binding removes */
if(lupnp->sip_udp != NULL) {
linphone_upnp_context_send_remove_port_binding(lupnp, lupnp->sip_udp);
- lupnp->sip_udp = NULL;
}
if(lupnp->sip_tcp != NULL) {
linphone_upnp_context_send_remove_port_binding(lupnp, lupnp->sip_tcp);
- lupnp->sip_tcp = NULL;
}
if(lupnp->sip_tls != NULL) {
linphone_upnp_context_send_remove_port_binding(lupnp, lupnp->sip_tls);
- lupnp->sip_tcp = NULL;
}
/* Wait all pending bindings are done */
upnp_igd_port_mapping mapping;
char description[128];
int ret;
+
+ if(lupnp->state != LinphoneUpnpStateOk) {
+ return -2;
+ }
// Compute port binding state
if(port->state != LinphoneUpnpStateAdding) {
int linphone_upnp_context_send_remove_port_binding(UpnpContext *lupnp, UpnpPortBinding *port) {
upnp_igd_port_mapping mapping;
int ret;
+
+ if(lupnp->state != LinphoneUpnpStateOk) {
+ return -2;
+ }
// Compute port binding state
if(port->state != LinphoneUpnpStateRemoving) {
void linphone_upnp_port_binding_log(int level, const char *msg, const UpnpPortBinding *port) {
if(strlen(port->local_addr)) {
- ortp_log(level, "uPnP IGD: %s %s|%d->%s:%d", msg,
+ ortp_log(level, "uPnP IGD: %s %s|%d->%s:%d (retry %d)", msg,
(port->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port->external_port,
port->local_addr,
- port->local_port);
+ port->local_port,
+ port->retry - 1);
} else {
- ortp_log(level, "uPnP IGD: %s %s|%d->%d", msg,
+ ortp_log(level, "uPnP IGD: %s %s|%d->%d (retry %d)", msg,
(port->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port->external_port,
- port->local_port);
+ port->local_port,
+ port->retry - 1);
}
}
return mValue;
}
}
+
+ static public class UpnpState {
+ static private Vector<UpnpState> values = new Vector<UpnpState>();
+ /**
+ * Idle
+ */
+ static public UpnpState Idle = new UpnpState(0, "Idle");
+ /**
+ * Pending
+ */
+ static public UpnpState Pending = new UpnpState(1, "Pending");
+ /**
+ * Adding
+ */
+ static public UpnpState Adding = new UpnpState(2, "Adding");
+ /**
+ * Removing
+ */
+ static public UpnpState Removing = new UpnpState(3, "Removing");
+ /**
+ * Not Available
+ */
+ static public UpnpState NotAvailable = new UpnpState(4, "Not available");
+ /**
+ * Ok
+ */
+ static public UpnpState Ok = new UpnpState(5, "Ok");
+ /**
+ * Ko
+ */
+ static public UpnpState Ko = new UpnpState(6, "Ko");
+ protected final int mValue;
+ private final String mStringValue;
+
+ private UpnpState(int value, String stringValue) {
+ mValue = value;
+ values.addElement(this);
+ mStringValue = stringValue;
+ }
+ public static UpnpState fromInt(int value) {
+ for (int i = 0; i < values.size(); i++) {
+ UpnpState mstate = (UpnpState) values.elementAt(i);
+ if (mstate.mValue == value) return mstate;
+ }
+ throw new RuntimeException("UpnpState not found [" + value + "]");
+ }
+ public String toString() {
+ return mStringValue;
+ }
+ }
/**
* Set the context of creation of the LinphoneCore.
* the config file with your own sections
*/
LpConfig getConfig();
+
+
+ /**
+ * Return the availability of uPnP.
+ *
+ * @return true if uPnP is available otherwise return false.
+ */
+ public boolean upnpAvailable();
+
+ /**
+ * Return the internal state of uPnP.
+ *
+ * @return an UpnpState.
+ */
+ public UpnpState getUpnpState();
+
+ /**
+ * Return the external ip address of router.
+ * In some cases the uPnP can have an external ip address but not a usable uPnP
+ * (state different of Ok).
+ *
+ * @return a null terminated string containing the external ip address. If the
+ * the external ip address is not available return null.
+ */
+ public String getUpnpExternalIpaddress();
+
}
long configPtr=getConfig(nativePtr);
return new LpConfigImpl(configPtr);
}
+
+ private native boolean upnpAvailable(long ptr);
+ public boolean upnpAvailable() {
+ return upnpAvailable(nativePtr);
+ }
+
+ private native int getUpnpState(long ptr);
+ public UpnpState getUpnpState() {
+ return UpnpState.fromInt(getUpnpState(nativePtr));
+ }
+
+ private native String getUpnpExternalIpaddress(long ptr);
+ public String getUpnpExternalIpaddress() {
+ return getUpnpExternalIpaddress(nativePtr);
+ }
}