mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
Merge branch 'ldap'
This commit is contained in:
commit
8d21c03f40
21 changed files with 2178 additions and 49 deletions
19
configure.ac
19
configure.ac
|
|
@ -165,6 +165,24 @@ AC_ARG_ENABLE(x11,
|
|||
[enable_x11=true]
|
||||
)
|
||||
|
||||
dnl conditional build of LDAP support
|
||||
AC_ARG_ENABLE(ldap,
|
||||
[AS_HELP_STRING([--disable-ldap], [Disable LDAP support (default=no)])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_ldap=true ;;
|
||||
no) enable_ldap=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-ldap) ;;
|
||||
esac],
|
||||
[enable_ldap=true]
|
||||
)
|
||||
|
||||
AM_CONDITIONAL(BUILD_LDAP, test x$enable_ldap != xfalse)
|
||||
if test "$enable_ldap" = "true"; then
|
||||
AC_CHECK_LIB(ldap,ldap_initialize, LDAP_LIBS="-lldap")
|
||||
AC_SUBST(LDAP_LIBS)
|
||||
AC_DEFINE(BUILD_LDAP,1,[Defined if LDAP build option enabled])
|
||||
fi
|
||||
|
||||
dnl conditionnal build of console interface.
|
||||
AC_ARG_ENABLE(console_ui,
|
||||
[AS_HELP_STRING([--enable-console_ui=[yes/no]], [Turn on or off compilation of console interface (default=yes)])],
|
||||
|
|
@ -864,6 +882,7 @@ printf "* %-30s %s\n" "Tools" $build_tools
|
|||
printf "* %-30s %s\n" "Message storage" $enable_msg_storage
|
||||
printf "* %-30s %s\n" "zRTP encryption (GPLv3)" $zrtp
|
||||
printf "* %-30s %s\n" "uPnP support" $build_upnp
|
||||
printf "* %-30s %s\n" "LDAP support" $enable_ldap
|
||||
|
||||
if test "$enable_tunnel" = "true" ; then
|
||||
printf "* %-30s %s\n" "Tunnel support" "true"
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ bin_PROGRAMS+=linphoned
|
|||
endif
|
||||
|
||||
linphonec_SOURCES=linphonec.c linphonec.h commands.c
|
||||
linphonec_CFLAGS=$(COMMON_CFLAGS) $(CONSOLE_FLAGS)
|
||||
linphonec_CFLAGS=$(COMMON_CFLAGS) $(CONSOLE_FLAGS) $(BELLESIP_CFLAGS)
|
||||
linphonec_LDADD=$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(READLINE_LIBS) \
|
||||
$(SQLITE3_LIBS) \
|
||||
$(X11_LIBS)
|
||||
$(X11_LIBS) \
|
||||
$(BELLESIP_LIBS)
|
||||
|
||||
if BUILD_WIN32
|
||||
#special build of linphonec to detach from the windows console
|
||||
|
|
|
|||
|
|
@ -48,11 +48,17 @@ liblinphone_la_SOURCES=\
|
|||
message_storage.c \
|
||||
info.c \
|
||||
event.c event.h \
|
||||
contactprovider.c contactprovider.h \
|
||||
dict.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
liblinphone_la_SOURCES+=upnp.c upnp.h
|
||||
endif
|
||||
|
||||
if BUILD_LDAP
|
||||
liblinphone_la_SOURCES+= ldap/ldapprovider.c ldap/ldapprovider.h
|
||||
endif
|
||||
|
||||
liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
|
||||
bellesip_sal/sal_impl.c bellesip_sal/sal_impl.h \
|
||||
|
|
@ -104,7 +110,8 @@ liblinphone_la_LIBADD= \
|
|||
$(TUNNEL_LIBS) \
|
||||
$(LIBSOUP_LIBS) \
|
||||
$(SQLITE3_LIBS) \
|
||||
$(LIBXML2_LIBS)
|
||||
$(LIBXML2_LIBS) \
|
||||
$(LDAP_LIBS)
|
||||
|
||||
|
||||
if ENABLE_TESTS
|
||||
|
|
|
|||
101
coreapi/contactprovider.c
Normal file
101
coreapi/contactprovider.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "contactprovider.h"
|
||||
#include <linphonecore.h>
|
||||
|
||||
/* LinphoneContactSearchRequest
|
||||
*/
|
||||
|
||||
void linphone_contact_search_init(LinphoneContactSearch* obj,
|
||||
const char* predicate,
|
||||
ContactSearchCallback cb,
|
||||
void* cb_data)
|
||||
{
|
||||
static unsigned int request_id_counter = 1;
|
||||
obj->id = request_id_counter++; // unique id
|
||||
obj->predicate = ms_strdup(predicate?predicate:"");
|
||||
obj->cb = cb;
|
||||
obj->data = cb_data;
|
||||
ms_message("LinphoneContactSearch@%p(id:%d, pred:%s, cb:%p, data:%p)",
|
||||
obj, obj->id, obj->predicate, obj->cb, obj->data);
|
||||
}
|
||||
|
||||
static void linphone_contact_search_destroy( LinphoneContactSearch* req) {
|
||||
ms_message( "~LinphoneContactSearch(%p)", req);
|
||||
if( req->predicate ) ms_free(req->predicate);
|
||||
}
|
||||
|
||||
ContactSearchID linphone_contact_search_get_id(LinphoneContactSearch* obj)
|
||||
{
|
||||
return obj->id;
|
||||
}
|
||||
|
||||
const char*linphone_contact_search_get_predicate(LinphoneContactSearch* obj)
|
||||
{
|
||||
return obj->predicate;
|
||||
}
|
||||
|
||||
void linphone_contact_search_invoke_cb(LinphoneContactSearch* req, MSList* friends)
|
||||
{
|
||||
if( req->cb ) req->cb(req, friends, req->data);
|
||||
}
|
||||
|
||||
int linphone_contact_search_compare(const void* a, const void* b) {
|
||||
LinphoneContactSearch *ra=((LinphoneContactSearch*)a);
|
||||
LinphoneContactSearch *rb=((LinphoneContactSearch*)b);
|
||||
return !(ra->id == rb->id); // return 0 if id is equal, 1 otherwise
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContactSearch);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneContactSearch,belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_contact_search_destroy,
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
FALSE
|
||||
);
|
||||
|
||||
/*
|
||||
* LinphoneContactProvider
|
||||
*/
|
||||
|
||||
|
||||
void linphone_contact_provider_init(LinphoneContactProvider* obj, LinphoneCore* lc){
|
||||
obj->lc = lc;
|
||||
}
|
||||
|
||||
static void contact_provider_destroy(LinphoneContactProvider* obj){
|
||||
(void)obj;
|
||||
}
|
||||
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContactProvider);
|
||||
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(LinphoneContactProvider)=
|
||||
{
|
||||
{
|
||||
BELLE_SIP_VPTR_INIT(LinphoneContactProvider,belle_sip_object_t,TRUE),
|
||||
(belle_sip_object_destroy_t) contact_provider_destroy,
|
||||
NULL,/*no clone*/
|
||||
NULL,/*no marshal*/
|
||||
},
|
||||
"",
|
||||
// Pure virtual
|
||||
NULL, /* begin_search -> pure virtual */
|
||||
NULL /* cancel_search -> pure virtual */
|
||||
};
|
||||
|
||||
|
||||
63
coreapi/contactprovider.h
Normal file
63
coreapi/contactprovider.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include "linphonecore.h"
|
||||
|
||||
/* LinphoneContactSearchRequest */
|
||||
|
||||
struct _LinphoneContactSearch{
|
||||
belle_sip_object_t base;
|
||||
ContactSearchID id;
|
||||
char* predicate;
|
||||
ContactSearchCallback cb;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#define LINPHONE_CONTACT_SEARCH(obj) BELLE_SIP_CAST(obj,LinphoneContactSearch)
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneContactSearch)
|
||||
|
||||
|
||||
void linphone_contact_search_init(LinphoneContactSearch* obj, const char* predicate, ContactSearchCallback cb, void* cb_data);
|
||||
ContactSearchID linphone_contact_search_get_id(LinphoneContactSearch* obj);
|
||||
const char* linphone_contact_search_get_predicate(LinphoneContactSearch* obj);
|
||||
void linphone_contact_search_invoke_cb(LinphoneContactSearch* req, MSList* friends);
|
||||
|
||||
|
||||
/* LinphoneContactProvider */
|
||||
|
||||
struct _LinphoneContactProvider {
|
||||
belle_sip_object_t base;
|
||||
LinphoneCore* lc;
|
||||
};
|
||||
|
||||
typedef struct _LinphoneContactProvider LinphoneContactProvider;
|
||||
typedef LinphoneContactSearch* (*LinphoneContactProviderStartSearchMethod)( LinphoneContactProvider* thiz, const char* predicate, ContactSearchCallback cb, void* data );
|
||||
typedef unsigned int (*LinphoneContactProviderCancelSearchMethod)( LinphoneContactProvider* thiz, LinphoneContactSearch *request );
|
||||
#define LINPHONE_CONTACT_PROVIDER(obj) BELLE_SIP_CAST(obj,LinphoneContactProvider)
|
||||
|
||||
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(LinphoneContactProvider,belle_sip_object_t)
|
||||
const char* name; /*!< Name of the contact provider (LDAP, Google, ...) */
|
||||
|
||||
/* pure virtual methods: inheriting objects must implement these */
|
||||
LinphoneContactProviderStartSearchMethod begin_search;
|
||||
LinphoneContactProviderCancelSearchMethod cancel_search;
|
||||
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
|
||||
|
||||
|
||||
void linphone_contact_provider_init(LinphoneContactProvider* obj, LinphoneCore* lc);
|
||||
LinphoneCore* linphone_contact_provider_get_core(LinphoneContactProvider* obj);
|
||||
const char* linphone_contact_provider_get_name(LinphoneContactProvider* obj);
|
||||
159
coreapi/dict.c
Normal file
159
coreapi/dict.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2009 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
|
||||
#include <belle-sip/belle-sip.h>
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup linphone_dict
|
||||
* @{
|
||||
**/
|
||||
|
||||
|
||||
LinphoneDictionary* linphone_dictionary_new()
|
||||
{
|
||||
return belle_sip_dict_create();
|
||||
}
|
||||
|
||||
LinphoneDictionary* linphone_dictionary_clone(const LinphoneDictionary* src)
|
||||
{
|
||||
LinphoneDictionary* cloned = linphone_dictionary_new();
|
||||
if( cloned ){
|
||||
belle_sip_dict_clone(src, cloned);
|
||||
}
|
||||
return cloned;
|
||||
}
|
||||
|
||||
LinphoneDictionary* linphone_dictionary_ref(LinphoneDictionary* obj)
|
||||
{
|
||||
return BELLE_SIP_DICT(belle_sip_object_ref(obj));
|
||||
}
|
||||
|
||||
void linphone_dictionary_unref(LinphoneDictionary *obj)
|
||||
{
|
||||
belle_sip_object_unref(obj);
|
||||
}
|
||||
|
||||
void linphone_dictionary_set_int(LinphoneDictionary* obj, const char* key, int value)
|
||||
{
|
||||
belle_sip_dict_set_int(obj, key, value);
|
||||
}
|
||||
|
||||
int linphone_dictionary_get_int(LinphoneDictionary* obj, const char* key, int default_value)
|
||||
{
|
||||
return belle_sip_dict_get_int(obj, key, default_value);
|
||||
}
|
||||
|
||||
void linphone_dictionary_set_string(LinphoneDictionary* obj, const char* key, const char*value)
|
||||
{
|
||||
belle_sip_dict_set_string(obj, key, value);
|
||||
}
|
||||
|
||||
const char* linphone_dictionary_get_string(LinphoneDictionary* obj, const char* key, const char* default_value)
|
||||
{
|
||||
return belle_sip_dict_get_string(obj, key, default_value);
|
||||
}
|
||||
|
||||
void linphone_dictionary_set_int64(LinphoneDictionary* obj, const char* key, int64_t value)
|
||||
{
|
||||
belle_sip_dict_set_int64(obj, key, value);
|
||||
}
|
||||
|
||||
int64_t linphone_dictionary_get_int64(LinphoneDictionary* obj, const char* key, int64_t default_value)
|
||||
{
|
||||
return belle_sip_dict_get_int64(obj, key, default_value);
|
||||
}
|
||||
|
||||
int linphone_dictionary_remove(LinphoneDictionary* obj, const char* key)
|
||||
{
|
||||
return belle_sip_dict_remove(obj, key);
|
||||
}
|
||||
|
||||
void linphone_dictionary_clear(LinphoneDictionary* obj)
|
||||
{
|
||||
belle_sip_dict_clear(obj);
|
||||
}
|
||||
|
||||
int linphone_dictionary_haskey(const LinphoneDictionary* obj, const char* key)
|
||||
{
|
||||
return belle_sip_dict_haskey(obj, key);
|
||||
}
|
||||
|
||||
void linphone_dictionary_foreach(const LinphoneDictionary* obj, void (*apply_func)(const char*, void*, void*), void* userdata)
|
||||
{
|
||||
return belle_sip_dict_foreach(obj, apply_func, userdata);
|
||||
}
|
||||
|
||||
struct lp_config_to_dict {
|
||||
const char* section;
|
||||
const LpConfig* config;
|
||||
LinphoneDictionary* dict;
|
||||
};
|
||||
|
||||
static void lp_config_section_to_dict_cb(const char*key, struct lp_config_to_dict* userdata)
|
||||
{
|
||||
const char* value = lp_config_get_string(userdata->config, userdata->section, key, "");
|
||||
linphone_dictionary_set_string(userdata->dict, key, value);
|
||||
}
|
||||
|
||||
LinphoneDictionary* lp_config_section_to_dict(const LpConfig* lpconfig, const char* section)
|
||||
{
|
||||
LinphoneDictionary* dict = NULL;
|
||||
struct lp_config_to_dict fd;
|
||||
fd.config = lpconfig;
|
||||
fd.section = section;
|
||||
|
||||
dict = linphone_dictionary_new();
|
||||
fd.dict = dict;
|
||||
|
||||
lp_config_for_each_entry(lpconfig, section,
|
||||
(void (*)(const char*, void*))lp_config_section_to_dict_cb,
|
||||
&fd);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
struct lp_config_from_dict {
|
||||
const char* section;
|
||||
LpConfig* config;
|
||||
};
|
||||
|
||||
static void lp_config_dict_dump_cb( const char* key, void* value, void* userdata)
|
||||
{
|
||||
struct lp_config_from_dict* fd= (struct lp_config_from_dict*)userdata;
|
||||
lp_config_set_string(fd->config, fd->section, key, (const char*)value);
|
||||
}
|
||||
|
||||
void lp_config_load_dict_to_section(LpConfig* lpconfig, const char* section, const LinphoneDictionary* dict)
|
||||
{
|
||||
struct lp_config_from_dict pvdata = { section, lpconfig };
|
||||
linphone_dictionary_foreach(dict,lp_config_dict_dump_cb, &pvdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
@ -53,7 +53,8 @@ LINPHONE_TUTOS=$(helloworld_SOURCES)
|
|||
|
||||
helloworld_LDADD=$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
$(ORTP_LIBS) \
|
||||
$(BELLESIP_LIBS)
|
||||
|
||||
registration_SOURCES=registration.c
|
||||
LINPHONE_TUTOS+=$(registration_SOURCES)
|
||||
|
|
@ -85,7 +86,8 @@ AM_CFLAGS=\
|
|||
-DLOG_DOMAIN=\"LinphoneCore\" \
|
||||
$(IPV6_CFLAGS) \
|
||||
-DORTP_INET6 \
|
||||
$(VIDEO_CFLAGS)
|
||||
$(VIDEO_CFLAGS) \
|
||||
$(BELLESIP_CFLAGS)
|
||||
|
||||
|
||||
tutodir=$(datadir)/tutorials/linphone
|
||||
|
|
|
|||
773
coreapi/ldap/ldapprovider.c
Normal file
773
coreapi/ldap/ldapprovider.c
Normal file
|
|
@ -0,0 +1,773 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "ldapprovider.h"
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
#include "lpconfig.h"
|
||||
#include <belle-sip/dict.h>
|
||||
|
||||
#include <ldap.h>
|
||||
#include <sasl/sasl.h>
|
||||
|
||||
|
||||
#define MAX_RUNNING_REQUESTS 10
|
||||
#define FILTER_MAX_SIZE 512
|
||||
|
||||
typedef enum {
|
||||
ANONYMOUS,
|
||||
PLAIN,
|
||||
SASL
|
||||
} LDAPAuthMethod;
|
||||
|
||||
struct LDAPFriendData {
|
||||
char* name;
|
||||
char* sip;
|
||||
};
|
||||
|
||||
struct _LinphoneLDAPContactProvider
|
||||
{
|
||||
LinphoneContactProvider base;
|
||||
LinphoneDictionary* config;
|
||||
|
||||
LDAP* ld;
|
||||
MSList* requests;
|
||||
uint req_count;
|
||||
|
||||
// bind transaction
|
||||
int bind_msgid;
|
||||
const char* auth_mechanism;
|
||||
bool_t connected;
|
||||
|
||||
// config
|
||||
int use_tls;
|
||||
LDAPAuthMethod auth_method;
|
||||
const char* username;
|
||||
const char* password;
|
||||
const char* server;
|
||||
|
||||
const char* base_object;
|
||||
const char* sip_attr;
|
||||
const char* name_attr;
|
||||
const char* filter;
|
||||
|
||||
char** attributes;
|
||||
|
||||
int timeout;
|
||||
int deref_aliases;
|
||||
int max_results;
|
||||
};
|
||||
|
||||
struct _LinphoneLDAPContactSearch
|
||||
{
|
||||
LinphoneContactSearch base;
|
||||
LDAP* ld;
|
||||
int msgid;
|
||||
char* filter;
|
||||
bool_t complete;
|
||||
MSList* found_entries;
|
||||
unsigned int found_count;
|
||||
};
|
||||
|
||||
|
||||
/* *************************
|
||||
* LinphoneLDAPContactSearch
|
||||
* *************************/
|
||||
|
||||
LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPContactProvider* cp, const char* predicate, ContactSearchCallback cb, void* cb_data)
|
||||
{
|
||||
LinphoneLDAPContactSearch* search = belle_sip_object_new(LinphoneLDAPContactSearch);
|
||||
LinphoneContactSearch* base = LINPHONE_CONTACT_SEARCH(search);
|
||||
struct timeval timeout = { cp->timeout, 0 };
|
||||
|
||||
linphone_contact_search_init(base, predicate, cb, cb_data);
|
||||
|
||||
search->ld = cp->ld;
|
||||
|
||||
search->filter = ms_malloc(FILTER_MAX_SIZE);
|
||||
snprintf(search->filter, FILTER_MAX_SIZE-1, cp->filter, predicate);
|
||||
search->filter[FILTER_MAX_SIZE-1] = 0;
|
||||
|
||||
ms_message("Calling ldap_search_ext with predicate '%s' on base %s", search->filter, cp->base_object);
|
||||
|
||||
int ret = ldap_search_ext(search->ld,
|
||||
cp->base_object, // base from which to start
|
||||
LDAP_SCOPE_SUBTREE,
|
||||
search->filter, // search predicate
|
||||
cp->attributes, // which attributes to get
|
||||
0, // 0 = get attrs AND value, 1 = get attrs only
|
||||
NULL,
|
||||
NULL,
|
||||
&timeout, // server timeout for the search
|
||||
cp->max_results,// max result number
|
||||
&search->msgid );
|
||||
|
||||
if( ret != LDAP_SUCCESS ){
|
||||
ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret));
|
||||
belle_sip_object_unref(search);
|
||||
return NULL;
|
||||
} else {
|
||||
ms_message("LinphoneLDAPContactSearch created @%p : msgid %d", search, search->msgid);
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||
void linphone_ldap_contact_search_destroy_friend( void* entry )
|
||||
{
|
||||
linphone_friend_destroy((LinphoneFriend*)entry);
|
||||
}
|
||||
|
||||
unsigned int linphone_ldap_contact_search_result_count(LinphoneLDAPContactSearch* obj)
|
||||
{
|
||||
return obj->found_count;
|
||||
}
|
||||
|
||||
|
||||
static void linphone_ldap_contact_search_destroy( LinphoneLDAPContactSearch* obj )
|
||||
{
|
||||
ms_message("~LinphoneLDAPContactSearch(%p)", obj);
|
||||
ms_list_for_each(obj->found_entries, linphone_ldap_contact_search_destroy_friend);
|
||||
obj->found_entries = ms_list_free(obj->found_entries);
|
||||
if( obj->filter ) ms_free(obj->filter);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactSearch);
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneLDAPContactSearch,LinphoneContactSearch,
|
||||
(belle_sip_object_destroy_t)linphone_ldap_contact_search_destroy,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
/* ***************************
|
||||
* LinphoneLDAPContactProvider
|
||||
* ***************************/
|
||||
|
||||
static inline LinphoneLDAPContactSearch* linphone_ldap_contact_provider_request_search( LinphoneLDAPContactProvider* obj, int msgid );
|
||||
static unsigned int linphone_ldap_contact_provider_cancel_search(LinphoneContactProvider* obj, LinphoneContactSearch *req);
|
||||
static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj );
|
||||
static bool_t linphone_ldap_contact_provider_iterate(void *data);
|
||||
static int linphone_ldap_contact_provider_bind_interact(LDAP *ld, unsigned flags, void *defaults, void *sasl_interact);
|
||||
|
||||
|
||||
/* Authentication methods */
|
||||
struct AuthMethodDescription{
|
||||
LDAPAuthMethod method;
|
||||
const char* description;
|
||||
};
|
||||
|
||||
static struct AuthMethodDescription ldap_auth_method_description[] = {
|
||||
{ANONYMOUS, "anonymous"},
|
||||
{PLAIN, "plain"},
|
||||
{SASL, "sasl"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static LDAPAuthMethod linphone_ldap_contact_provider_auth_method( const char* description )
|
||||
{
|
||||
struct AuthMethodDescription* desc = ldap_auth_method_description;
|
||||
while( desc && desc->description ){
|
||||
if( strcmp(description, desc->description) == 0)
|
||||
return desc->method;
|
||||
desc++;
|
||||
}
|
||||
return ANONYMOUS;
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_destroy_request_cb(void *req)
|
||||
{
|
||||
belle_sip_object_unref(req);
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_destroy( LinphoneLDAPContactProvider* obj )
|
||||
{
|
||||
ms_message("linphone_ldap_contact_provider_destroy");
|
||||
linphone_core_remove_iterate_hook(LINPHONE_CONTACT_PROVIDER(obj)->lc, linphone_ldap_contact_provider_iterate,obj);
|
||||
|
||||
// clean pending requests
|
||||
ms_list_for_each(obj->requests, linphone_ldap_contact_provider_destroy_request_cb);
|
||||
|
||||
if (obj->ld) ldap_unbind_ext(obj->ld, NULL, NULL);
|
||||
obj->ld = NULL;
|
||||
|
||||
if( obj->config ) linphone_dictionary_unref(obj->config);
|
||||
|
||||
linphone_ldap_contact_provider_conf_destroy(obj);
|
||||
}
|
||||
|
||||
static int linphone_ldap_contact_provider_parse_bind_results( LinphoneLDAPContactProvider* obj, LDAPMessage* results )
|
||||
{
|
||||
int ret;
|
||||
if( obj->auth_method == ANONYMOUS ) {
|
||||
ms_message("ANONYMOUS BIND OK");
|
||||
ret = LDAP_SUCCESS;
|
||||
} else {
|
||||
ms_message("COMPLICATED BIND follow-up");
|
||||
ret = ldap_sasl_interactive_bind(obj->ld,
|
||||
NULL, // dn, should be NULL
|
||||
"DIGEST-MD5",
|
||||
NULL,NULL, // server and client controls
|
||||
LDAP_SASL_QUIET, // never prompt, only use callback
|
||||
linphone_ldap_contact_provider_bind_interact, // callback to call when info is needed
|
||||
obj, // private data
|
||||
results, // result, to pass later on when a ldap_result() comes
|
||||
&obj->auth_mechanism,
|
||||
&obj->bind_msgid );
|
||||
if( ret != LDAP_SUCCESS){
|
||||
ms_error("ldap_parse_sasl_bind_result failed(%d)", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if( ret == LDAP_SUCCESS ){
|
||||
obj->connected = TRUE;
|
||||
obj->bind_msgid = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int linphone_ldap_contact_provider_complete_contact( LinphoneLDAPContactProvider* obj, struct LDAPFriendData* lf, const char* attr_name, const char* attr_value)
|
||||
{
|
||||
if( strcmp(attr_name, obj->name_attr ) == 0 ){
|
||||
lf->name = ms_strdup(attr_value);
|
||||
} else if( strcmp(attr_name, obj->sip_attr) == 0 ) {
|
||||
lf->sip = ms_strdup(attr_value);
|
||||
}
|
||||
|
||||
// return 1 if the structure has enough data to create a linphone friend
|
||||
if( lf->name && lf->sip )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_handle_search_result( LinphoneLDAPContactProvider* obj, LinphoneLDAPContactSearch* req, LDAPMessage* message )
|
||||
{
|
||||
int msgtype = ldap_msgtype(message);
|
||||
|
||||
switch(msgtype){
|
||||
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
case LDAP_RES_EXTENDED:
|
||||
{
|
||||
LDAPMessage *entry = ldap_first_entry(obj->ld, message);
|
||||
LinphoneCore* lc = LINPHONE_CONTACT_PROVIDER(obj)->lc;
|
||||
|
||||
while( entry != NULL ){
|
||||
|
||||
struct LDAPFriendData ldap_data = {0};
|
||||
bool_t contact_complete = FALSE;
|
||||
BerElement* ber = NULL;
|
||||
char* attr = ldap_first_attribute(obj->ld, entry, &ber);
|
||||
char* dn = ldap_get_dn(obj->ld, entry);
|
||||
|
||||
|
||||
if( dn ){
|
||||
//ms_message("search result: dn: %s", dn);
|
||||
ldap_memfree(dn);
|
||||
}
|
||||
|
||||
while( attr ){
|
||||
struct berval** values = ldap_get_values_len(obj->ld, entry, attr);
|
||||
struct berval** it = values;
|
||||
|
||||
while( values && *it && (*it)->bv_val && (*it)->bv_len )
|
||||
{
|
||||
//ms_message("%s -> %s", attr, (*it)->bv_val);
|
||||
|
||||
contact_complete = linphone_ldap_contact_provider_complete_contact(obj, &ldap_data, attr, (*it)->bv_val);
|
||||
if( contact_complete ) break;
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
if( values ) ldap_value_free_len(values);
|
||||
ldap_memfree(attr);
|
||||
|
||||
if( contact_complete ) break;
|
||||
|
||||
attr = ldap_next_attribute(obj->ld, entry, ber);
|
||||
}
|
||||
|
||||
if( contact_complete ) {
|
||||
LinphoneAddress* la = linphone_core_interpret_url(lc, ldap_data.sip);
|
||||
if( la ){
|
||||
LinphoneFriend* lf = linphone_core_create_friend(lc);
|
||||
linphone_friend_set_address(lf, la);
|
||||
linphone_friend_set_name(lf, ldap_data.name);
|
||||
req->found_entries = ms_list_append(req->found_entries, lf);
|
||||
req->found_count++;
|
||||
//ms_message("Added friend %s / %s", ldap_data.name, ldap_data.sip);
|
||||
ms_free(ldap_data.sip);
|
||||
ms_free(ldap_data.name);
|
||||
linphone_address_destroy(la);
|
||||
}
|
||||
}
|
||||
|
||||
if( ber ) ber_free(ber, 0);
|
||||
|
||||
entry = ldap_next_entry(obj->ld, entry);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
{
|
||||
// this one is received when a request is finished
|
||||
req->complete = TRUE;
|
||||
linphone_contact_search_invoke_cb(LINPHONE_CONTACT_SEARCH(req), req->found_entries);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default: ms_message("[LDAP] Unhandled message type %x", msgtype); break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t linphone_ldap_contact_provider_iterate(void *data)
|
||||
{
|
||||
LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data);
|
||||
if( obj->ld && ((obj->req_count > 0) || (obj->bind_msgid != 0) )){
|
||||
|
||||
// never block
|
||||
struct timeval timeout = {0,0};
|
||||
LDAPMessage* results = NULL;
|
||||
|
||||
int ret = ldap_result(obj->ld, LDAP_RES_ANY, LDAP_MSG_ONE, &timeout, &results);
|
||||
|
||||
if( ret != 0 && ret != -1) ms_message("ldap_result %x", ret);
|
||||
|
||||
switch( ret ){
|
||||
case -1:
|
||||
{
|
||||
ms_warning("Error in ldap_result : returned -1 (req_count %d, bind_msgid %d): %s", obj->req_count, obj->bind_msgid, ldap_err2string(errno));
|
||||
break;
|
||||
}
|
||||
case 0: break; // nothing to do
|
||||
|
||||
case LDAP_RES_BIND:
|
||||
{
|
||||
ms_message("iterate: LDAP_RES_BIND");
|
||||
if( ldap_msgid( results ) != obj->bind_msgid ) {
|
||||
ms_error("Bad msgid");
|
||||
} else {
|
||||
linphone_ldap_contact_provider_parse_bind_results( obj, results );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LDAP_RES_EXTENDED:
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
case LDAP_RES_SEARCH_REFERENCE:
|
||||
case LDAP_RES_INTERMEDIATE:
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
{
|
||||
LDAPMessage* message = ldap_first_message(obj->ld, results);
|
||||
LinphoneLDAPContactSearch* req = linphone_ldap_contact_provider_request_search(obj, ldap_msgid(message));
|
||||
while( message != NULL ){
|
||||
//ms_message("Message @%p:id %d / type %x / associated request: %p", message, ldap_msgid(message), ldap_msgtype(message), req);
|
||||
linphone_ldap_contact_provider_handle_search_result(obj, req, message );
|
||||
message = ldap_next_message(obj->ld, message);
|
||||
}
|
||||
if( req && ret == LDAP_RES_SEARCH_RESULT) linphone_ldap_contact_provider_cancel_search(LINPHONE_CONTACT_PROVIDER(obj), LINPHONE_CONTACT_SEARCH(req));
|
||||
break;
|
||||
}
|
||||
case LDAP_RES_MODIFY:
|
||||
case LDAP_RES_ADD:
|
||||
case LDAP_RES_DELETE:
|
||||
case LDAP_RES_MODDN:
|
||||
case LDAP_RES_COMPARE:
|
||||
default:
|
||||
ms_message("Unhandled LDAP result %x", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if( results )
|
||||
ldap_msgfree(results);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj )
|
||||
{
|
||||
if(obj->attributes){
|
||||
int i=0;
|
||||
for( ; obj->attributes[i]; i++){
|
||||
ms_free(obj->attributes[i]);
|
||||
}
|
||||
ms_free(obj->attributes);
|
||||
}
|
||||
}
|
||||
|
||||
static char* required_config_keys[] = {
|
||||
// connection
|
||||
"server",
|
||||
"use_tls",
|
||||
"auth_method",
|
||||
"username",
|
||||
"password",
|
||||
|
||||
// search
|
||||
"base_object",
|
||||
"filter",
|
||||
"name_attribute",
|
||||
"sip_attribute",
|
||||
"attributes",
|
||||
|
||||
// misc
|
||||
"timeout",
|
||||
"max_results",
|
||||
"deref_aliases",
|
||||
NULL
|
||||
};
|
||||
|
||||
static bool_t linphone_ldap_contact_provider_valid_config(const LinphoneDictionary* dict)
|
||||
{
|
||||
char** config_name = required_config_keys;
|
||||
|
||||
bool_t valid = TRUE;
|
||||
bool_t has_key;
|
||||
|
||||
while(*config_name ){
|
||||
has_key = linphone_dictionary_haskey(dict, *config_name);
|
||||
if( !has_key ) ms_error("Missing LDAP config value for '%s'", *config_name);
|
||||
valid &= has_key;
|
||||
config_name++;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvider* obj, const LinphoneDictionary* dict)
|
||||
{
|
||||
char* attributes_list, *saveptr, *attr;
|
||||
unsigned int attr_count = 0, attr_idx = 0, i;
|
||||
|
||||
if( !linphone_ldap_contact_provider_valid_config(dict) ) return;
|
||||
|
||||
// free any pre-existing attributes values
|
||||
linphone_ldap_contact_provider_conf_destroy(obj);
|
||||
if( obj->config ) linphone_dictionary_unref(obj->config);
|
||||
|
||||
// clone new config into the dictionary
|
||||
obj->config = linphone_dictionary_ref(linphone_dictionary_clone(dict));
|
||||
|
||||
obj->use_tls = linphone_dictionary_get_int(obj->config, "use_tls", 0);
|
||||
obj->timeout = linphone_dictionary_get_int(obj->config, "timeout", 10);
|
||||
obj->deref_aliases = linphone_dictionary_get_int(obj->config, "deref_aliases", 0);
|
||||
obj->max_results = linphone_dictionary_get_int(obj->config, "max_results", 50);
|
||||
obj->username = linphone_dictionary_get_string(obj->config, "username", "");
|
||||
obj->password = linphone_dictionary_get_string(obj->config, "password", "");
|
||||
obj->base_object = linphone_dictionary_get_string(obj->config, "base_object", "dc=example,dc=com");
|
||||
obj->server = linphone_dictionary_get_string(obj->config, "server", "ldap://192.168.0.230:10389");
|
||||
obj->filter = linphone_dictionary_get_string(obj->config, "filter", "uid=*%s*");
|
||||
obj->name_attr = linphone_dictionary_get_string(obj->config, "name_attribute", "givenName");
|
||||
obj->sip_attr = linphone_dictionary_get_string(obj->config, "sip_attribute", "mobile");
|
||||
|
||||
/*
|
||||
* Get authentication method
|
||||
*/
|
||||
obj->auth_method = linphone_ldap_contact_provider_auth_method(
|
||||
linphone_dictionary_get_string(obj->config, "auth_method", "anonymous")
|
||||
);
|
||||
|
||||
/*
|
||||
* parse the attributes list
|
||||
*/
|
||||
attributes_list = ms_strdup(
|
||||
linphone_dictionary_get_string(obj->config,
|
||||
"attributes",
|
||||
"telephoneNumber,givenName,sn,mobile,homePhone")
|
||||
);
|
||||
|
||||
// count attributes:
|
||||
for( i=0; attributes_list[i]; i++) {
|
||||
if( attributes_list[i] == ',') attr_count++;
|
||||
}
|
||||
|
||||
// 1 more for the first attr without ',', the other for the null-finished list
|
||||
obj->attributes = ms_malloc0((attr_count+2) * sizeof(char*));
|
||||
|
||||
attr = strtok_r( attributes_list, ",", &saveptr );
|
||||
while( attr != NULL ){
|
||||
obj->attributes[attr_idx] = ms_strdup(attr);
|
||||
attr_idx++;
|
||||
attr = strtok_r(NULL, ",", &saveptr);
|
||||
}
|
||||
if( attr_idx != attr_count+1) ms_error("Invalid attribute number!!! %d expected, got %d", attr_count+1, attr_idx);
|
||||
|
||||
ms_free(attributes_list);
|
||||
}
|
||||
|
||||
static int linphone_ldap_contact_provider_bind_interact(LDAP *ld,
|
||||
unsigned flags,
|
||||
void *defaults,
|
||||
void *sasl_interact)
|
||||
{
|
||||
sasl_interact_t *interact = (sasl_interact_t*)sasl_interact;
|
||||
LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(defaults);
|
||||
ms_message("bind_interact called: ld %p, flags %x, default %p, interact %p",
|
||||
ld, flags, defaults, sasl_interact);
|
||||
|
||||
if( ld == NULL ) return LDAP_PARAM_ERROR;
|
||||
|
||||
while( interact->id != SASL_CB_LIST_END ) {
|
||||
|
||||
const char *dflt = interact->defresult;
|
||||
|
||||
switch( interact->id ) {
|
||||
case SASL_CB_GETREALM:
|
||||
ms_message("* SASL_CB_GETREALM");
|
||||
dflt=NULL;
|
||||
break;
|
||||
case SASL_CB_USER:
|
||||
case SASL_CB_AUTHNAME:
|
||||
ms_message("* SASL_CB_AUTHNAME -> %s", obj->username);
|
||||
dflt=obj->username;
|
||||
break;
|
||||
case SASL_CB_PASS:
|
||||
ms_message("* SASL_CB_PASS -> %s", obj->password);
|
||||
dflt=obj->password;
|
||||
break;
|
||||
default:
|
||||
ms_message("my_sasl_interact asked for unknown %lx\n",interact->id);
|
||||
}
|
||||
interact->result = (dflt && *dflt) ? dflt : (const char*)"";
|
||||
interact->len = strlen( (const char*)interact->result );
|
||||
|
||||
interact++;
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj )
|
||||
{
|
||||
int ret;
|
||||
const char* auth_mechanism = linphone_dictionary_get_string(obj->config, "auth_method", "anonymous");
|
||||
LDAPAuthMethod method = obj->auth_method;
|
||||
|
||||
if( method == ANONYMOUS ){
|
||||
// for anonymous authentication, use a simple sasl_bind
|
||||
struct berval creds = {strlen(obj->password), ms_strdup(obj->password)};
|
||||
ret = ldap_sasl_bind(obj->ld, obj->base_object, NULL, &creds, NULL, NULL, &obj->bind_msgid);
|
||||
if(creds.bv_val) ms_free(creds.bv_val);
|
||||
} else {
|
||||
ret = ldap_sasl_interactive_bind(obj->ld,
|
||||
NULL, // dn, should be NULL
|
||||
"SIMPLE",//"DIGEST-MD5",
|
||||
NULL,NULL, // server and client controls
|
||||
LDAP_SASL_QUIET, // never prompt, only use callback
|
||||
linphone_ldap_contact_provider_bind_interact, // callback to call when info is needed
|
||||
obj, // private data
|
||||
NULL, // result, to pass later on when a ldap_result() comes
|
||||
&obj->auth_mechanism,
|
||||
&obj->bind_msgid );
|
||||
}
|
||||
if( ret == LDAP_SUCCESS || ret == LDAP_SASL_BIND_IN_PROGRESS ) {
|
||||
if( ret == LDAP_SASL_BIND_IN_PROGRESS) ms_message("BIND_IN_PROGRESS");
|
||||
ms_message("LDAP bind request sent, auth: %s, msgid %x", obj->auth_mechanism?obj->auth_mechanism:"-", obj->bind_msgid);
|
||||
} else {
|
||||
int err;
|
||||
ldap_get_option(obj->ld, LDAP_OPT_RESULT_CODE, &err);
|
||||
ms_error("ldap_sasl_bind error returned %d, err %d (%s), auth_method: %s",
|
||||
ret, err, ldap_err2string(err), auth_mechanism );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int linphone_ldap_contact_provider_get_max_result(const LinphoneLDAPContactProvider* obj)
|
||||
{
|
||||
return obj->max_results;
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_provider_config_dump_cb(const char*key, void* value, void* userdata)
|
||||
{
|
||||
ms_message("- %s -> %s", key, (const char* )value);
|
||||
}
|
||||
|
||||
LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore* lc, const LinphoneDictionary* config)
|
||||
{
|
||||
LinphoneLDAPContactProvider* obj = belle_sip_object_new(LinphoneLDAPContactProvider);
|
||||
int proto_version = LDAP_VERSION3;
|
||||
|
||||
linphone_contact_provider_init((LinphoneContactProvider*)obj, lc);
|
||||
|
||||
ms_message( "Constructed Contact provider '%s'", BELLE_SIP_OBJECT_VPTR(obj,LinphoneContactProvider)->name);
|
||||
|
||||
if( !linphone_ldap_contact_provider_valid_config(config) ) {
|
||||
ms_error( "Invalid configuration for LDAP, aborting creation");
|
||||
belle_sip_object_unref(obj);
|
||||
obj = NULL;
|
||||
} else {
|
||||
linphone_dictionary_foreach( config, linphone_ldap_contact_provider_config_dump_cb, 0 );
|
||||
linphone_ldap_contact_provider_loadconfig(obj, config);
|
||||
|
||||
int ret = ldap_initialize(&(obj->ld),obj->server);
|
||||
|
||||
if( ret != LDAP_SUCCESS ){
|
||||
ms_error( "Problem initializing ldap on url '%s': %s", obj->server, ldap_err2string(ret));
|
||||
belle_sip_object_unref(obj);
|
||||
obj = NULL;
|
||||
} else if( (ret = ldap_set_option(obj->ld, LDAP_OPT_PROTOCOL_VERSION, &proto_version)) != LDAP_SUCCESS ){
|
||||
ms_error( "Problem setting protocol version %d: %s", proto_version, ldap_err2string(ret));
|
||||
belle_sip_object_unref(obj);
|
||||
obj = NULL;
|
||||
} else {
|
||||
// register our hook into iterate so that LDAP can do its magic asynchronously.
|
||||
//linphone_ldap_contact_provider_bind(obj);
|
||||
linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an LDAP request in the list of current LDAP requests to serve, only taking
|
||||
* the msgid as a key to search.
|
||||
*/
|
||||
static int linphone_ldap_request_entry_compare_weak(const void*a, const void* b)
|
||||
{
|
||||
const LinphoneLDAPContactSearch* ra = (const LinphoneLDAPContactSearch*)a;
|
||||
const LinphoneLDAPContactSearch* rb = (const LinphoneLDAPContactSearch*)b;
|
||||
return !(ra->msgid == rb->msgid); // 0 if equal
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an LDAP request in the list of current LDAP requests to serve, with strong search
|
||||
* comparing both msgid and request pointer
|
||||
*/
|
||||
static int linphone_ldap_request_entry_compare_strong(const void*a, const void* b)
|
||||
{
|
||||
const LinphoneLDAPContactSearch* ra = (const LinphoneLDAPContactSearch*)a;
|
||||
const LinphoneLDAPContactSearch* rb = (const LinphoneLDAPContactSearch*)b;
|
||||
return !(ra->msgid == rb->msgid) && !(ra == rb);
|
||||
}
|
||||
|
||||
static inline LinphoneLDAPContactSearch* linphone_ldap_contact_provider_request_search( LinphoneLDAPContactProvider* obj, int msgid )
|
||||
{
|
||||
LinphoneLDAPContactSearch dummy = {};
|
||||
dummy.msgid = msgid;
|
||||
|
||||
MSList* list_entry = ms_list_find_custom(obj->requests, linphone_ldap_request_entry_compare_weak, &dummy);
|
||||
if( list_entry ) return list_entry->data;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static unsigned int linphone_ldap_contact_provider_cancel_search(LinphoneContactProvider* obj, LinphoneContactSearch *req)
|
||||
{
|
||||
LinphoneLDAPContactSearch* ldap_req = LINPHONE_LDAP_CONTACT_SEARCH(req);
|
||||
LinphoneLDAPContactProvider* ldap_cp = LINPHONE_LDAP_CONTACT_PROVIDER(obj);
|
||||
int ret = 1;
|
||||
|
||||
MSList* list_entry = ms_list_find_custom(ldap_cp->requests, linphone_ldap_request_entry_compare_strong, req);
|
||||
if( list_entry ) {
|
||||
ldap_cp->requests = ms_list_remove_link(ldap_cp->requests, list_entry);
|
||||
ldap_cp->req_count--;
|
||||
ret = 0; // return OK if we found it in the monitored requests
|
||||
} else {
|
||||
ms_warning("Couldn't find ldap request %p (id %d) in monitoring.", ldap_req, ldap_req->msgid);
|
||||
}
|
||||
belle_sip_object_unref(req); // unref request even if not found
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LinphoneLDAPContactSearch* linphone_ldap_contact_provider_begin_search ( LinphoneLDAPContactProvider* obj,
|
||||
const char* predicate,
|
||||
ContactSearchCallback cb,
|
||||
void* cb_data )
|
||||
{
|
||||
// if we're not yet connected, bind
|
||||
if( !obj->connected ) linphone_ldap_contact_provider_bind(obj);
|
||||
|
||||
LinphoneLDAPContactSearch* request = linphone_ldap_contact_search_create ( obj, predicate, cb, cb_data );
|
||||
|
||||
if ( request != NULL ) {
|
||||
ms_message ( "Created search %d for '%s', msgid %d, @%p", obj->req_count, predicate, request->msgid, request );
|
||||
|
||||
obj->requests = ms_list_append ( obj->requests, request );
|
||||
obj->req_count++;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
static int linphone_ldap_contact_provider_marshal(LinphoneLDAPContactProvider* obj, char* buff, size_t buff_size, size_t *offset)
|
||||
{
|
||||
belle_sip_error_code error = BELLE_SIP_OK;
|
||||
|
||||
error = belle_sip_snprintf(buff, buff_size, offset, "ld:%p,\n", obj->ld);
|
||||
if(error!= BELLE_SIP_OK) return error;
|
||||
|
||||
error = belle_sip_snprintf(buff, buff_size, offset, "req_count:%d,\n", obj->req_count);
|
||||
if(error!= BELLE_SIP_OK) return error;
|
||||
|
||||
error = belle_sip_snprintf(buff, buff_size, offset, "bind_msgid:%d,\n", obj->bind_msgid);
|
||||
if(error!= BELLE_SIP_OK) return error;
|
||||
|
||||
error = belle_sip_snprintf(buff, buff_size, offset,
|
||||
"CONFIG:\n"
|
||||
"tls: %d \n"
|
||||
"auth: %d \n"
|
||||
"user: %s \n"
|
||||
"pass: %s \n"
|
||||
"server: %s \n"
|
||||
"base: %s \n"
|
||||
"filter: %s \n"
|
||||
"timeout: %d \n"
|
||||
"deref: %d \n"
|
||||
"max_res: %d \n"
|
||||
"sip_attr:%s \n"
|
||||
"name_attr:%s \n"
|
||||
"attrs:\n",
|
||||
obj->use_tls, obj->auth_method,
|
||||
obj->username, obj->password, obj->server,
|
||||
obj->base_object, obj->filter,
|
||||
obj->timeout, obj->deref_aliases,
|
||||
obj->max_results,
|
||||
obj->sip_attr, obj->name_attr);
|
||||
if(error!= BELLE_SIP_OK) return error;
|
||||
|
||||
char **attr = obj->attributes;
|
||||
while( *attr ){
|
||||
error = belle_sip_snprintf(buff, buff_size, offset, "- %s\n", *attr);
|
||||
if(error!= BELLE_SIP_OK) return error;
|
||||
else attr++;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactProvider);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(LinphoneLDAPContactProvider)=
|
||||
{
|
||||
{
|
||||
{
|
||||
BELLE_SIP_VPTR_INIT(LinphoneLDAPContactProvider,LinphoneContactProvider,TRUE),
|
||||
(belle_sip_object_destroy_t)linphone_ldap_contact_provider_destroy,
|
||||
NULL,
|
||||
(belle_sip_object_marshal_t)linphone_ldap_contact_provider_marshal
|
||||
},
|
||||
"LDAP",
|
||||
(LinphoneContactProviderStartSearchMethod)linphone_ldap_contact_provider_begin_search,
|
||||
(LinphoneContactProviderCancelSearchMethod)linphone_ldap_contact_provider_cancel_search
|
||||
}
|
||||
};
|
||||
|
||||
45
coreapi/ldap/ldapprovider.h
Normal file
45
coreapi/ldap/ldapprovider.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "contactprovider.h"
|
||||
|
||||
#include <ldap.h>
|
||||
|
||||
typedef struct _LinphoneLDAPContactProvider LinphoneLDAPContactProvider;
|
||||
|
||||
/* LinphoneLDAPContactSearch */
|
||||
typedef struct _LinphoneLDAPContactSearch LinphoneLDAPContactSearch;
|
||||
|
||||
#define LINPHONE_LDAP_CONTACT_SEARCH(obj) BELLE_SIP_CAST(obj,LinphoneLDAPContactSearch)
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneLDAPContactSearch)
|
||||
|
||||
LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPContactProvider* ld,
|
||||
const char* predicate,
|
||||
ContactSearchCallback cb,
|
||||
void* cb_data);
|
||||
|
||||
unsigned int linphone_ldap_contact_search_result_count(LinphoneLDAPContactSearch* obj);
|
||||
|
||||
|
||||
/* LinphoneLDAPContactProvider */
|
||||
|
||||
#define LINPHONE_LDAP_CONTACT_PROVIDER(obj) BELLE_SIP_CAST(obj,LinphoneLDAPContactProvider)
|
||||
|
||||
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(LinphoneLDAPContactProvider,LinphoneContactProvider)
|
||||
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
|
||||
|
||||
LinphoneLDAPContactProvider* linphone_ldap_contact_provider_create(LinphoneCore* lc, const LinphoneDictionary* config);
|
||||
unsigned int linphone_ldap_contact_provider_get_max_result(const LinphoneLDAPContactProvider* obj);
|
||||
|
|
@ -1350,6 +1350,7 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
|
|||
lc->tunnel=linphone_core_tunnel_new(lc);
|
||||
if (lc->tunnel) linphone_tunnel_configure(lc->tunnel);
|
||||
#endif
|
||||
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Ready"));
|
||||
lc->auto_net_state_mon=lc->sip_conf.auto_net_state_mon;
|
||||
|
|
@ -5674,16 +5675,23 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
}
|
||||
#endif //BUILD_UPNP
|
||||
|
||||
#ifdef BUILD_LDAP
|
||||
if( lc->ldap != NULL ) {
|
||||
belle_sip_object_unref(lc->ldap);
|
||||
lc->ldap = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config);
|
||||
lp_config_destroy(lc->config);
|
||||
lc->config = NULL; /* Mark the config as NULL to block further calls */
|
||||
|
||||
ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_destroy);
|
||||
lc->call_logs=ms_list_free(lc->call_logs);
|
||||
|
||||
|
||||
ms_list_for_each(lc->last_recv_msg_ids,ms_free);
|
||||
lc->last_recv_msg_ids=ms_list_free(lc->last_recv_msg_ids);
|
||||
|
||||
|
||||
// Free struct variable
|
||||
if(lc->zrtp_secrets_cache != NULL) {
|
||||
ms_free(lc->zrtp_secrets_cache);
|
||||
|
|
@ -6287,5 +6295,3 @@ void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path){
|
|||
linphone_core_message_storage_init(lc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "lpconfig.h"
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
||||
#define LINPHONE_IPADDR_SIZE 64
|
||||
#define LINPHONE_HOSTNAME_SIZE 128
|
||||
|
||||
|
|
@ -118,6 +121,8 @@ typedef enum _LinphoneTransportType LinphoneTransportType;
|
|||
*/
|
||||
typedef struct SalAddress LinphoneAddress;
|
||||
|
||||
typedef struct belle_sip_dict LinphoneDictionary;
|
||||
|
||||
/**
|
||||
* The LinphoneContent struct holds data that can be embedded in a signaling message.
|
||||
* @ingroup misc
|
||||
|
|
@ -181,6 +186,37 @@ typedef enum _LinphoneReason LinphoneReason;
|
|||
**/
|
||||
const char *linphone_reason_to_string(LinphoneReason err);
|
||||
|
||||
|
||||
/* linphone dictionary */
|
||||
LINPHONE_PUBLIC LinphoneDictionary* linphone_dictionary_new();
|
||||
LinphoneDictionary * linphone_dictionary_clone(const LinphoneDictionary* src);
|
||||
LinphoneDictionary * linphone_dictionary_ref(LinphoneDictionary* obj);
|
||||
void linphone_dictionary_unref(LinphoneDictionary* obj);
|
||||
LINPHONE_PUBLIC void linphone_dictionary_set_int(LinphoneDictionary* obj, const char* key, int value);
|
||||
LINPHONE_PUBLIC int linphone_dictionary_get_int(LinphoneDictionary* obj, const char* key, int default_value);
|
||||
LINPHONE_PUBLIC void linphone_dictionary_set_string(LinphoneDictionary* obj, const char* key, const char*value);
|
||||
LINPHONE_PUBLIC const char* linphone_dictionary_get_string(LinphoneDictionary* obj, const char* key, const char* default_value);
|
||||
LINPHONE_PUBLIC void linphone_dictionary_set_int64(LinphoneDictionary* obj, const char* key, int64_t value);
|
||||
LINPHONE_PUBLIC int64_t linphone_dictionary_get_int64(LinphoneDictionary* obj, const char* key, int64_t default_value);
|
||||
LINPHONE_PUBLIC int linphone_dictionary_remove(LinphoneDictionary* obj, const char* key);
|
||||
LINPHONE_PUBLIC void linphone_dictionary_clear(LinphoneDictionary* obj);
|
||||
LINPHONE_PUBLIC int linphone_dictionary_haskey(const LinphoneDictionary* obj, const char* key);
|
||||
LINPHONE_PUBLIC void linphone_dictionary_foreach( const LinphoneDictionary* obj, void (*apply_func)(const char*key, void* value, void* userdata), void* userdata);
|
||||
/**
|
||||
* Converts a config section into a dictionary.
|
||||
* @return a #LinphoneDictionary with all the keys from a section, or NULL if the section doesn't exist
|
||||
* @ingroup misc
|
||||
*/
|
||||
LinphoneDictionary* lp_config_section_to_dict( const LpConfig* lpconfig, const char* section );
|
||||
|
||||
/**
|
||||
* Loads a dictionary into a section of the lpconfig. If the section doesn't exist it is created.
|
||||
* Overwrites existing keys, creates non-existing keys.
|
||||
* @ingroup misc
|
||||
*/
|
||||
void lp_config_load_dict_to_section( LpConfig* lpconfig, const char* section, const LinphoneDictionary* dict);
|
||||
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonefriend.h"
|
||||
#include "event.h"
|
||||
|
|
@ -402,7 +438,7 @@ typedef enum _LinphonePrivacy {
|
|||
*
|
||||
**/
|
||||
LinphonePrivacyCritical=0x10,
|
||||
|
||||
|
||||
/**
|
||||
* Special keyword to use privacy as defined either globally or by proxy using linphone_proxy_config_set_privacy()
|
||||
*/
|
||||
|
|
@ -442,7 +478,7 @@ LINPHONE_PUBLIC LinphoneInfoMessage *linphone_info_message_copy(const LinphoneIn
|
|||
* @ingroup media_parameters
|
||||
**/
|
||||
struct _LinphoneVideoPolicy{
|
||||
bool_t automatically_initiate; /**<Whether video shall be automatically proposed for outgoing calls.*/
|
||||
bool_t automatically_initiate; /**<Whether video shall be automatically proposed for outgoing calls.*/
|
||||
bool_t automatically_accept; /**<Whether video shall be automatically accepted for incoming calls*/
|
||||
bool_t unused[2];
|
||||
};
|
||||
|
|
@ -901,7 +937,7 @@ struct _LinphoneChatRoom;
|
|||
* <br> Can be created by linphone_chat_room_create_message().
|
||||
*/
|
||||
typedef struct _LinphoneChatMessage LinphoneChatMessage;
|
||||
|
||||
|
||||
/**
|
||||
* A chat room is the place where text messages are exchanged.
|
||||
* <br> Can be created by linphone_core_create_chat_room().
|
||||
|
|
@ -945,7 +981,7 @@ LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoo
|
|||
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud);
|
||||
LINPHONE_PUBLIC void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC MSList* linphone_core_get_chat_rooms(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC MSList* linphone_core_get_chat_rooms(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
|
||||
|
||||
LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state);
|
||||
|
|
@ -1023,23 +1059,23 @@ typedef void (*LinphoneCoreCallEncryptionChangedCb)(LinphoneCore *lc, LinphoneCa
|
|||
* Registration state notification callback prototype
|
||||
* */
|
||||
typedef void (*LinphoneCoreRegistrationStateChangedCb)(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message);
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
*/
|
||||
typedef void (*ShowInterfaceCb)(LinphoneCore *lc);
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
*/
|
||||
typedef void (*DisplayStatusCb)(LinphoneCore *lc, const char *message);
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
*/
|
||||
typedef void (*DisplayMessageCb)(LinphoneCore *lc, const char *message);
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
/** Callback prototype
|
||||
* @deprecated
|
||||
*/
|
||||
typedef void (*DisplayUrlCb)(LinphoneCore *lc, const char *message, const char *url);
|
||||
/** Callback prototype
|
||||
/** Callback prototype
|
||||
*/
|
||||
typedef void (*LinphoneCoreCbFunc)(LinphoneCore *lc,void * user_data);
|
||||
/**
|
||||
|
|
@ -1057,7 +1093,7 @@ typedef void (*LinphoneCoreNotifyPresenceReceivedCb)(LinphoneCore *lc, LinphoneF
|
|||
* Callback prototype
|
||||
*/
|
||||
typedef void (*LinphoneCoreNewSubscriptionRequestedCb)(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
/**
|
||||
/**
|
||||
* Callback for requesting authentication information to application or user.
|
||||
* @param lc the LinphoneCore
|
||||
* @param realm the realm (domain) on which authentication is required.
|
||||
|
|
@ -1066,7 +1102,7 @@ typedef void (*LinphoneCoreNewSubscriptionRequestedCb)(LinphoneCore *lc, Linphon
|
|||
*/
|
||||
typedef void (*LinphoneCoreAuthInfoRequestedCb)(LinphoneCore *lc, const char *realm, const char *username, const char *domain);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Callback to notify a new call-log entry has been added.
|
||||
* This is done typically when a call terminates.
|
||||
* @param lc the LinphoneCore
|
||||
|
|
@ -1093,8 +1129,8 @@ typedef void (*LinphoneCoreTextMessageReceivedCb)(LinphoneCore *lc, LinphoneChat
|
|||
* @param LinphoneChatMessage incoming message
|
||||
*/
|
||||
typedef void (*LinphoneCoreMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Callback for being notified of DTMFs received.
|
||||
* @param lc the linphone core
|
||||
* @param call the call that received the dtmf
|
||||
|
|
@ -1114,7 +1150,7 @@ typedef void (*LinphoneCoreBuddyInfoUpdatedCb)(LinphoneCore *lc, LinphoneFriend
|
|||
*/
|
||||
typedef void (*LinphoneCoreTransferStateChangedCb)(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Callback for receiving quality statistics for calls.
|
||||
* @param lc the LinphoneCore
|
||||
* @param call the call
|
||||
|
|
@ -1122,11 +1158,11 @@ typedef void (*LinphoneCoreTransferStateChangedCb)(LinphoneCore *lc, LinphoneCal
|
|||
*/
|
||||
typedef void (*LinphoneCoreCallStatsUpdatedCb)(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Callback prototype for receiving info messages.
|
||||
* @param lc the LinphoneCore
|
||||
* @param call the call whose info message belongs to.
|
||||
* @param msg the info message.
|
||||
* @param msg the info message.
|
||||
*/
|
||||
typedef void (*LinphoneCoreInfoReceivedCb)(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
|
||||
|
|
@ -1431,7 +1467,7 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadT
|
|||
* @param rate can be #LINPHONE_FIND_PAYLOAD_IGNORE_RATE
|
||||
* @param channels number of channels, can be #LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS
|
||||
* @return Returns NULL if not found.
|
||||
*/
|
||||
*/
|
||||
LINPHONE_PUBLIC PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ;
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
|
@ -1447,7 +1483,7 @@ LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *
|
|||
* @ingroup proxy
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc);
|
||||
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_clear_proxy_config(LinphoneCore *lc);
|
||||
|
|
@ -1604,28 +1640,28 @@ LINPHONE_PUBLIC const char * linphone_core_get_stun_server(const LinphoneCore *l
|
|||
* @ingroup network_parameters
|
||||
* Return the availability of uPnP.
|
||||
*
|
||||
* @return true if uPnP is available otherwise return false.
|
||||
* @return true if uPnP is available otherwise return false.
|
||||
*/
|
||||
bool_t linphone_core_upnp_available();
|
||||
|
||||
/**
|
||||
* @ingroup network_parameters
|
||||
* Return the internal state of uPnP.
|
||||
* Return the internal state of uPnP.
|
||||
*
|
||||
* @param lc #LinphoneCore
|
||||
* @return an LinphoneUpnpState.
|
||||
* @return an LinphoneUpnpState.
|
||||
*/
|
||||
LinphoneUpnpState linphone_core_get_upnp_state(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* @ingroup network_parameters
|
||||
* Return the external ip address of router.
|
||||
* 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).
|
||||
* (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.
|
||||
* the external ip address is not available return null.
|
||||
*/
|
||||
const char * linphone_core_get_upnp_external_ipaddress(const LinphoneCore *lc);
|
||||
|
||||
|
|
@ -2167,6 +2203,23 @@ LINPHONE_PUBLIC const char *linphone_core_get_video_display_filter(LinphoneCore
|
|||
LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, const char *filtername);
|
||||
|
||||
|
||||
/** Contact Providers
|
||||
*/
|
||||
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch)
|
||||
BELLE_SIP_DECLARE_TYPES_END
|
||||
|
||||
typedef unsigned int ContactSearchID;
|
||||
|
||||
struct _LinphoneContactSearch;
|
||||
typedef struct _LinphoneContactSearch LinphoneContactSearch;
|
||||
|
||||
typedef void (*ContactSearchCallback)( LinphoneContactSearch* id, MSList* friends, void* data );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,6 +74,10 @@ extern "C" {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_LDAP
|
||||
#include "ldap/ldapprovider.h"
|
||||
#endif
|
||||
|
||||
struct _LinphoneCallParams{
|
||||
LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
|
||||
int audio_bw; /* bandwidth limit for audio stream */
|
||||
|
|
@ -656,6 +660,10 @@ struct _LinphoneCore
|
|||
#ifdef BUILD_UPNP
|
||||
UpnpContext *upnp;
|
||||
#endif //BUILD_UPNP
|
||||
|
||||
#ifdef BUILD_LDAP
|
||||
LinphoneLDAPContactProvider* ldap;
|
||||
#endif //BUILD_LDAP
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ linphone_SOURCES+= \
|
|||
endif
|
||||
|
||||
linphone_LDADD= $(top_builddir)/coreapi/liblinphone.la \
|
||||
$(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) $(SQLITE3_LIBS)
|
||||
$(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) $(SQLITE3_LIBS) $(BELLESIP_LIBS)
|
||||
|
||||
|
||||
if BUILD_WIN32
|
||||
|
|
@ -77,7 +77,7 @@ endif
|
|||
|
||||
AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(ORTP_CFLAGS) $(BELLESIP_CFLAGS) \
|
||||
$(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) $(IPV6_CFLAGS) \
|
||||
$(TUNNEL_CFLAGS) \
|
||||
$(SQLITE3_CFLAGS)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
#include "linphonecore.h"
|
||||
|
||||
#ifdef BUILD_LDAP
|
||||
#include "ldap/ldapprovider.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# undef _
|
||||
|
|
@ -46,6 +51,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define LINPHONE_VERSION LINPHONE_VERSION_DATE
|
||||
#endif
|
||||
|
||||
enum {
|
||||
COMPLETION_HISTORY,
|
||||
COMPLETION_LDAP
|
||||
};
|
||||
|
||||
GdkPixbuf * create_pixbuf(const gchar *filename);
|
||||
GdkPixbufAnimation *create_pixbuf_animation(const gchar *filename);
|
||||
void add_pixmap_directory(const gchar *directory);
|
||||
|
|
@ -63,6 +73,8 @@ void linphone_gtk_show_assistant(void);
|
|||
void linphone_gtk_close_assistant(void);
|
||||
|
||||
LinphoneCore *linphone_gtk_get_core(void);
|
||||
LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void);
|
||||
void linphone_gtk_set_ldap(LinphoneLDAPContactProvider* ldap);
|
||||
GtkWidget *linphone_gtk_get_main_window();
|
||||
void linphone_gtk_display_something(GtkMessageType type,const gchar *message);
|
||||
void linphone_gtk_start_call(GtkWidget *button);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "linphone.h"
|
||||
|
||||
void linphone_gtk_login_frame_connect_clicked(GtkWidget *button);
|
||||
void test_button_clicked_cb(GtkWidget *button);
|
||||
void linphone_gtk_exit_login_frame(void);
|
||||
|
||||
enum {
|
||||
|
|
|
|||
185
gtk/main.c
185
gtk/main.c
|
|
@ -50,6 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
|
||||
|
||||
static LinphoneCore *the_core=NULL;
|
||||
static LinphoneLDAPContactProvider* ldap_provider = NULL;
|
||||
static GtkWidget *the_ui=NULL;
|
||||
|
||||
static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg);
|
||||
|
|
@ -69,7 +70,7 @@ void linphone_gtk_save_main_window_position(GtkWindow* mw, GdkEvent *event, gpoi
|
|||
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
|
||||
void linphone_gtk_status_icon_set_blinking(gboolean val);
|
||||
void _linphone_gtk_enable_video(gboolean val);
|
||||
|
||||
void linphone_gtk_on_uribar_changed(GtkEditable *uribar, gpointer user_data);
|
||||
|
||||
#ifndef HAVE_GTK_OSX
|
||||
static gint main_window_x=0;
|
||||
|
|
@ -231,6 +232,23 @@ static const char *linphone_gtk_get_factory_config_file(){
|
|||
return _factory_config_file;
|
||||
}
|
||||
|
||||
LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void){
|
||||
#ifdef BUILD_LDAP
|
||||
return ldap_provider;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void linphone_gtk_set_ldap(LinphoneLDAPContactProvider* ldap)
|
||||
{
|
||||
if( ldap_provider )
|
||||
belle_sip_object_unref(ldap_provider);
|
||||
|
||||
ldap_provider = ldap ? LINPHONE_LDAP_CONTACT_PROVIDER(belle_sip_object_ref( ldap ))
|
||||
: NULL;
|
||||
}
|
||||
|
||||
static void linphone_gtk_init_liblinphone(const char *config_file,
|
||||
const char *factory_config_file, const char *db_file) {
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
|
@ -256,7 +274,16 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
|
||||
the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL);
|
||||
//lp_config_set_int(linphone_core_get_config(the_core), "sip", "store_auth_info", 0);
|
||||
|
||||
|
||||
|
||||
#ifdef BUILD_LDAP
|
||||
if( lp_config_has_section(linphone_core_get_config(the_core),"ldap") ){
|
||||
LpConfig* cfg = linphone_core_get_config(the_core);
|
||||
LinphoneDictionary* ldap_cfg = lp_config_section_to_dict(cfg, "ldap");
|
||||
linphone_gtk_set_ldap( linphone_ldap_contact_provider_create(the_core, ldap_cfg) );
|
||||
}
|
||||
#endif
|
||||
|
||||
linphone_core_set_user_agent(the_core,"Linphone", LINPHONE_VERSION);
|
||||
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
|
||||
linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
|
||||
|
|
@ -279,7 +306,7 @@ GtkWidget *linphone_gtk_get_main_window(){
|
|||
}
|
||||
|
||||
void linphone_gtk_destroy_main_window() {
|
||||
linphone_gtk_destroy_window(the_ui);
|
||||
linphone_gtk_destroy_window(the_ui);
|
||||
the_ui = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -629,12 +656,31 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean uribar_completion_matchfunc(GtkEntryCompletion *completion, const gchar *key, GtkTreeIter *iter, gpointer user_data){
|
||||
char* address = NULL;
|
||||
gboolean ret = FALSE;
|
||||
gchar *tmp= NULL;
|
||||
gtk_tree_model_get(gtk_entry_completion_get_model(completion),iter,0,&address,-1);
|
||||
|
||||
tmp = g_utf8_casefold(address,-1);
|
||||
if (tmp){
|
||||
if (strstr(tmp,key))
|
||||
ret=TRUE;
|
||||
g_free(tmp);
|
||||
}
|
||||
|
||||
if( address)
|
||||
g_free(address);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void load_uri_history(){
|
||||
GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar"));
|
||||
char key[20];
|
||||
int i;
|
||||
GtkEntryCompletion *gep=gtk_entry_completion_new();
|
||||
GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING);
|
||||
GtkListStore *model=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_INT);
|
||||
for (i=0;;i++){
|
||||
const char *uri;
|
||||
snprintf(key,sizeof(key),"uri%i",i);
|
||||
|
|
@ -642,14 +688,18 @@ static void load_uri_history(){
|
|||
if (uri!=NULL) {
|
||||
GtkTreeIter iter;
|
||||
gtk_list_store_append(model,&iter);
|
||||
gtk_list_store_set(model,&iter,0,uri,-1);
|
||||
gtk_list_store_set(model,&iter,0,uri,1,COMPLETION_HISTORY,-1);
|
||||
if (i==0) gtk_entry_set_text(uribar,uri);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model));
|
||||
gtk_entry_completion_set_text_column(gep,0);
|
||||
gtk_entry_completion_set_popup_completion(gep, TRUE);
|
||||
gtk_entry_completion_set_match_func(gep,uribar_completion_matchfunc, NULL, NULL);
|
||||
gtk_entry_completion_set_minimum_key_length(gep,3);
|
||||
gtk_entry_set_completion(uribar,gep);
|
||||
g_signal_connect (G_OBJECT (uribar), "changed", G_CALLBACK(linphone_gtk_on_uribar_changed), NULL);
|
||||
}
|
||||
|
||||
static void save_uri_history(){
|
||||
|
|
@ -697,10 +747,130 @@ static void completion_add_text(GtkEntry *entry, const char *text){
|
|||
}
|
||||
/* and prepend it on top of the list */
|
||||
gtk_list_store_prepend(GTK_LIST_STORE(model),&iter);
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1);
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,1,COMPLETION_HISTORY,-1);
|
||||
save_uri_history();
|
||||
}
|
||||
|
||||
void on_contact_provider_search_results( LinphoneContactSearch* req, MSList* friends, void* data )
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkEntry* uribar = GTK_ENTRY(data);
|
||||
GtkEntryCompletion* compl = gtk_entry_get_completion(uribar);
|
||||
GtkTreeModel* model = gtk_entry_completion_get_model(compl);
|
||||
GtkListStore* list = GTK_LIST_STORE(model);
|
||||
gboolean valid;
|
||||
|
||||
// clear completion list from previous non-history entries
|
||||
valid = gtk_tree_model_get_iter_first(model,&iter);
|
||||
while(valid)
|
||||
{
|
||||
char* url;
|
||||
int type;
|
||||
gtk_tree_model_get(model,&iter, 0,&url, 1,&type, -1);
|
||||
|
||||
if (type != COMPLETION_HISTORY) {
|
||||
valid = gtk_list_store_remove(list, &iter);
|
||||
} else {
|
||||
valid = gtk_tree_model_iter_next(model,&iter);
|
||||
}
|
||||
|
||||
if( url ) g_free(url);
|
||||
if( !valid ) break;
|
||||
}
|
||||
|
||||
// add new non-history related matches
|
||||
while( friends ){
|
||||
LinphoneFriend* lf = friends->data;
|
||||
if( lf ) {
|
||||
const LinphoneAddress* la = linphone_friend_get_address(lf);
|
||||
if( la ){
|
||||
char *addr = linphone_address_as_string(la);
|
||||
|
||||
if( addr ){
|
||||
ms_message("[LDAP]Insert match: %s", addr);
|
||||
gtk_list_store_insert_with_values(list, &iter, -1,
|
||||
0, addr,
|
||||
1, COMPLETION_LDAP, -1);
|
||||
ms_free(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
friends = friends->next;
|
||||
}
|
||||
gtk_entry_completion_complete(compl);
|
||||
// save the number of LDAP results to better decide if new results should be fetched when search predicate gets bigger
|
||||
gtk_object_set_data(GTK_OBJECT(uribar), "ldap_res_cout",
|
||||
GINT_TO_POINTER(
|
||||
linphone_ldap_contact_search_result_count(LINPHONE_LDAP_CONTACT_SEARCH(req))
|
||||
)
|
||||
);
|
||||
|
||||
// Gtk bug? we need to emit a "changed" signal so that the completion appears if
|
||||
// the list of results was previously empty
|
||||
g_signal_handlers_block_by_func(uribar, linphone_gtk_on_uribar_changed, NULL);
|
||||
g_signal_emit_by_name(uribar, "changed");
|
||||
g_signal_handlers_unblock_by_func(uribar, linphone_gtk_on_uribar_changed, NULL);
|
||||
}
|
||||
|
||||
struct CompletionTimeout {
|
||||
guint timeout_id;
|
||||
};
|
||||
|
||||
static gboolean launch_contact_provider_search(void *userdata)
|
||||
{
|
||||
LinphoneLDAPContactProvider* ldap = linphone_gtk_get_ldap();
|
||||
GtkWidget* uribar = GTK_WIDGET(userdata);
|
||||
const gchar* predicate = gtk_entry_get_text(GTK_ENTRY(uribar));
|
||||
gchar* previous_search = gtk_object_get_data(GTK_OBJECT(uribar), "previous_search");
|
||||
unsigned int prev_res_count = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(uribar), "ldap_res_cout"));
|
||||
|
||||
if( ldap && strlen(predicate) >= 3 ){ // don't search too small predicates
|
||||
unsigned int max_res_count = linphone_ldap_contact_provider_get_max_result(ldap);
|
||||
|
||||
if( previous_search &&
|
||||
(strstr(predicate, previous_search) == predicate) && // last search contained results from this one
|
||||
(prev_res_count != max_res_count) ){ // and we didn't reach the max result limit
|
||||
|
||||
ms_message("Don't launch search on already searched data (current: %s, old search: %s), (%d/%d results)",
|
||||
predicate, previous_search, prev_res_count, max_res_count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save current search
|
||||
if( previous_search ) ms_free(previous_search);
|
||||
gtk_object_set_data(GTK_OBJECT(uribar), "previous_search", ms_strdup(predicate));
|
||||
|
||||
ms_message("launch_contact_provider_search");
|
||||
LinphoneContactSearch* search =
|
||||
BELLE_SIP_OBJECT_VPTR(ldap,LinphoneContactProvider)->begin_search(
|
||||
LINPHONE_CONTACT_PROVIDER(ldap),
|
||||
predicate,
|
||||
on_contact_provider_search_results,
|
||||
uribar);
|
||||
|
||||
if(search)
|
||||
belle_sip_object_ref(search);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_gtk_on_uribar_changed(GtkEditable *uribar, gpointer user_data)
|
||||
{
|
||||
#ifdef BUILD_LDAP
|
||||
gchar* text = gtk_editable_get_chars(uribar, 0,-1);
|
||||
gint timeout = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(uribar), "complete_timeout"));
|
||||
if( text ) g_free(text);
|
||||
|
||||
if( timeout != 0 ) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
|
||||
timeout = g_timeout_add_seconds(1,(GSourceFunc)launch_contact_provider_search, uribar);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(uribar),"complete_timeout", GINT_TO_POINTER(timeout) );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool_t linphone_gtk_video_enabled(void){
|
||||
const LinphoneVideoPolicy *vpol=linphone_core_get_video_policy(linphone_gtk_get_core());
|
||||
return vpol->automatically_accept && vpol->automatically_initiate;
|
||||
|
|
@ -1873,6 +2043,9 @@ static void linphone_gtk_quit(void){
|
|||
g_source_remove_by_user_data(linphone_gtk_get_core());
|
||||
#ifdef BUILD_WIZARD
|
||||
linphone_gtk_close_assistant();
|
||||
#endif
|
||||
#ifdef BUILD_LDAP
|
||||
linphone_gtk_set_ldap(NULL);
|
||||
#endif
|
||||
linphone_gtk_uninit_instance();
|
||||
linphone_gtk_destroy_log_window();
|
||||
|
|
|
|||
11
gtk/main.ui
11
gtk/main.ui
|
|
@ -1109,6 +1109,12 @@
|
|||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -1547,8 +1553,8 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="proxy_refresh_button">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="relief">none</property>
|
||||
|
|
@ -1762,6 +1768,9 @@
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment10">
|
||||
<property name="upper">500</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment2">
|
||||
<property name="lower">1</property>
|
||||
<property name="upper">65535</property>
|
||||
|
|
@ -54,6 +60,12 @@
|
|||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment9">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">10</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment_max_audio_port">
|
||||
<property name="upper">65535</property>
|
||||
<property name="step_increment">2</property>
|
||||
|
|
@ -81,6 +93,23 @@
|
|||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="liststore1"/>
|
||||
<object class="GtkListStore" id="liststore2">
|
||||
<columns>
|
||||
<!-- column-name authmethod -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">anonymous</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">GSSAPI</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">SASL</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model1">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
|
|
@ -2428,6 +2457,540 @@
|
|||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="ldap_tab">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label41">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xpad">1</property>
|
||||
<property name="label" translatable="yes">Server address:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label43">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Authentication method:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label44">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Username:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label45">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Password:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="ldap_use_tls">
|
||||
<property name="label" translatable="yes">Use TLS Connection</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_server">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_username">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_password">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="ldap_auth_method">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">liststore2</property>
|
||||
<property name="row_span_column">0</property>
|
||||
<property name="column_span_column">0</property>
|
||||
<property name="active">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="renderer1"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label17">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Connection</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label46">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Base object:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label47">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Filter (%s for name):</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label48">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Name Attribute:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label49">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">SIP address attribute:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label50">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Attributes to query:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_base_object">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_filter">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_name_attribute">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_sip_attribute">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ldap_attributes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label37">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Search</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label51">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Timeout for search:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label52">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Max results:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="ldap_timeout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
<property name="adjustment">adjustment9</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="ldap_max_results">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">3</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
<property name="secondary_icon_sensitive">True</property>
|
||||
<property name="adjustment">adjustment10</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="ldap_deref_aliases">
|
||||
<property name="label" translatable="yes">Follow Aliases</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label40">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Miscellaneous</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox20">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="ldap_save">
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="linphone_gtk_ldap_save" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="ldap_reset">
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="linphone_gtk_ldap_reset" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkHBox" id="hbox19">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-disconnect</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label16">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">LDAP</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "linphone.h"
|
||||
#include "linphone_tunnel.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
typedef enum {
|
||||
CAP_IGNORE,
|
||||
|
|
@ -59,6 +60,131 @@ static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices,
|
|||
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
|
||||
}
|
||||
|
||||
static void linphone_gtk_ldap_load_settings(GtkWidget* param)
|
||||
{
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
|
||||
LpConfig* config = linphone_core_get_config(linphone_gtk_get_core());
|
||||
LinphoneDictionary* ldap_conf = lp_config_section_to_dict(config,"ldap");
|
||||
GtkEntry* entry;
|
||||
GtkToggleButton* toggle;
|
||||
GtkSpinButton* spin;
|
||||
|
||||
|
||||
toggle = GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ldap_use_tls"));
|
||||
gtk_toggle_button_set_active(toggle, linphone_dictionary_get_int(ldap_conf,"use_tls", 0) );
|
||||
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_server"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"server", "ldap://example.com") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_username"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"username", "") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_password"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"password", "") );
|
||||
|
||||
// TODO
|
||||
// GtkComboBox* cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"ldap_auth_method"));
|
||||
// gtk_combo_box_set_active(entry, linphone_dictionary_get_string(ldap_conf,"auth_method", "anonymous") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_base_object"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"base_object", "dc=example,dc=com") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_filter"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"filter", "uid=*%s*") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_name_attribute"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"name_attribute", "cn") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_sip_attribute"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"sip_attribute", "mobile") );
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_attributes"));
|
||||
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"attributes", "cn,givenName,sn,mobile,homePhone") );
|
||||
|
||||
|
||||
toggle = GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ldap_deref_aliases"));
|
||||
gtk_toggle_button_set_active(toggle, linphone_dictionary_get_int(ldap_conf,"deref_aliases", 0) );
|
||||
|
||||
spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_max_results"));
|
||||
gtk_spin_button_set_value(spin, linphone_dictionary_get_int(ldap_conf,"max_results", 50) );
|
||||
|
||||
spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_timeout"));
|
||||
gtk_spin_button_set_value(spin, linphone_dictionary_get_int(ldap_conf,"timeout", 10) );
|
||||
|
||||
}
|
||||
|
||||
void linphone_gtk_ldap_reset(GtkWidget *tabmgr)
|
||||
{
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
|
||||
ms_message("RESET LDAP");
|
||||
linphone_gtk_ldap_load_settings(pb);
|
||||
}
|
||||
|
||||
void linphone_gtk_ldap_save(GtkWidget *tabmgr)
|
||||
{
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
LpConfig* conf = linphone_core_get_config(lc);
|
||||
LinphoneDictionary* dict = linphone_dictionary_new();
|
||||
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *pb = (GtkWidget *) g_object_get_data(G_OBJECT(mw), "parameters");
|
||||
GtkEntry* entry;
|
||||
GtkToggleButton* toggle;
|
||||
GtkSpinButton* spin;
|
||||
|
||||
ms_message("SAVE LDAP");
|
||||
|
||||
toggle = GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ldap_use_tls"));
|
||||
linphone_dictionary_set_int(dict, "use_tls", gtk_toggle_button_get_active(toggle));
|
||||
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_server"));
|
||||
linphone_dictionary_set_string(dict, "server", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_username"));
|
||||
linphone_dictionary_set_string(dict, "username", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_password"));
|
||||
linphone_dictionary_set_string(dict, "password", gtk_entry_get_text(entry));
|
||||
|
||||
|
||||
GtkComboBox* cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"ldap_auth_method"));
|
||||
linphone_dictionary_set_string(dict, "auth_method", gtk_combo_box_get_active_text(cbox));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_base_object"));
|
||||
linphone_dictionary_set_string(dict, "base_object", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_filter"));
|
||||
linphone_dictionary_set_string(dict, "filter", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_name_attribute"));
|
||||
linphone_dictionary_set_string(dict, "name_attribute", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_sip_attribute"));
|
||||
linphone_dictionary_set_string(dict, "sip_attribute", gtk_entry_get_text(entry));
|
||||
|
||||
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_attributes"));
|
||||
linphone_dictionary_set_string(dict, "attributes", gtk_entry_get_text(entry));
|
||||
|
||||
toggle = GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ldap_deref_aliases"));
|
||||
linphone_dictionary_set_int(dict, "deref_aliases", gtk_toggle_button_get_active(toggle));
|
||||
|
||||
spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_max_results"));
|
||||
linphone_dictionary_set_int(dict, "max_results", gtk_spin_button_get_value(spin) );
|
||||
|
||||
spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_timeout"));
|
||||
linphone_dictionary_set_int(dict, "timeout", gtk_spin_button_get_value(spin) );
|
||||
|
||||
ms_message("Create LDAP from config");
|
||||
// create new LDAP according to the validated config
|
||||
linphone_gtk_set_ldap( linphone_ldap_contact_provider_create(lc, dict) );
|
||||
// save the config to linphonerc:
|
||||
lp_config_load_dict_to_section(conf, "ldap", dict);
|
||||
}
|
||||
|
||||
void linphone_gtk_fill_video_sizes(GtkWidget *combo){
|
||||
const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
|
||||
int i,active=0;
|
||||
|
|
@ -1301,6 +1427,15 @@ void linphone_gtk_show_parameters(void){
|
|||
gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_label")), TRUE);
|
||||
}
|
||||
|
||||
/* LDAP CONFIG */
|
||||
#ifdef BUILD_LDAP
|
||||
linphone_gtk_ldap_load_settings(pb);
|
||||
#else
|
||||
// hide the LDAP tab
|
||||
GtkNotebook* notebook = GTK_NOTEBOOK(linphone_gtk_get_widget(pb, "notebook1"));
|
||||
gtk_notebook_remove_page(notebook,5);
|
||||
#endif
|
||||
|
||||
gtk_widget_show(pb);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ liblinphone_tester_SOURCES= liblinphone_tester.c liblinphone_tester.h\
|
|||
|
||||
AM_CPPFLAGS=-I$(top_srcdir)/include -I$(top_srcdir)/coreapi
|
||||
|
||||
LDADD=$(top_builddir)/coreapi/liblinphone.la
|
||||
LDADD=$(top_builddir)/coreapi/liblinphone.la $(BELLESIP_LIBS)
|
||||
|
||||
AM_LDFLAGS=$(CUNIT_LIBS)
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS)
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS)
|
||||
|
||||
test: liblinphone_tester
|
||||
./liblinphone_tester --config $(abs_srcdir)
|
||||
|
|
|
|||
|
|
@ -1053,7 +1053,6 @@ static void early_media_call_forking(void) {
|
|||
linphone_core_use_files (marie1->lc,TRUE);
|
||||
linphone_core_set_play_file(marie1->lc,ringbackpath);
|
||||
|
||||
|
||||
linphone_core_enable_video(marie2->lc,TRUE,TRUE);
|
||||
linphone_core_set_video_policy(marie2->lc,&pol);
|
||||
linphone_core_set_audio_port_range(marie2->lc,40200,40300);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue