Christmas Presence

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3083 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-10-18 22:57:35 +00:00
parent 61e118db18
commit 70bfba5b63
19 changed files with 2163 additions and 179 deletions

View File

@ -53,7 +53,7 @@ DIST_COMMON = README $(am__configure_deps) $(library_include_HEADERS) \
ChangeLog INSTALL NEWS build/config/compile \
build/config/config.guess build/config/config.sub \
build/config/depcomp build/config/install-sh \
build/config/ltmain.sh build/config/missing mkinstalldirs
build/config/ltmain.sh build/config/missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in

View File

@ -56,6 +56,12 @@ else
fi
fi
if [ ! -f $root/.nothanks ] && [ $uncompressed/.complete -ot $uncompressed ] ; then
echo remove stale .complete
rm $uncompressed/.complete
cd $uncompressed && $MAKE clean distclean
fi
if [ -f $uncompressed/.complete ] ; then
echo $uncompressed already installed
exit 0

View File

@ -17,7 +17,7 @@ AM_CFLAGS += $(shell $(APU_CONFIG) --includes)
AM_LDFLAGS += $(shell $(APU_CONFIG) --link-ld --libs )
lib_LTLIBRARIES = libdingaling.la
libdingaling_la_SOURCES = src/libdingaling.c
libdingaling_la_SOURCES = src/libdingaling.c src/sha1.c
libdingaling_la_CFLAGS = $(AM_CFLAGS)
libdingaling_la_LDFLAGS =

View File

@ -39,9 +39,9 @@ build_triplet = @build@
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(library_include_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
compile config.guess config.sub depcomp install-sh ltmain.sh \
missing mkinstalldirs
$(top_srcdir)/configure $(top_srcdir)/src/config.h.in AUTHORS \
COPYING ChangeLog INSTALL NEWS compile config.guess config.sub \
depcomp install-sh ltmain.sh missing mkinstalldirs
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
@ -50,6 +50,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@ -62,9 +63,10 @@ am__installdirs = "$(DESTDIR)$(libdir)" \
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libdingaling_la_LIBADD =
am_libdingaling_la_OBJECTS = libdingaling_la-libdingaling.lo
am_libdingaling_la_OBJECTS = libdingaling_la-libdingaling.lo \
libdingaling_la-sha1.lo
libdingaling_la_OBJECTS = $(am_libdingaling_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@ -210,7 +212,7 @@ AM_LDFLAGS = -liksemel -L$(PREFIX)/lib $(shell $(APR_CONFIG) --link-ld \
APR_CONFIG = $(prefix)/bin/apr-1-config
APU_CONFIG = $(prefix)/bin/apu-1-config
lib_LTLIBRARIES = libdingaling.la
libdingaling_la_SOURCES = src/libdingaling.c
libdingaling_la_SOURCES = src/libdingaling.c src/sha1.c
libdingaling_la_CFLAGS = $(AM_CFLAGS)
libdingaling_la_LDFLAGS =
library_includedir = $(prefix)/include
@ -252,6 +254,23 @@ $(top_srcdir)/configure: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
src/config.h: src/stamp-h1
@if test ! -f $@; then \
rm -f src/stamp-h1; \
$(MAKE) src/stamp-h1; \
else :; fi
src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
@rm -f src/stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/config.h
$(top_srcdir)/src/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f src/stamp-h1
touch $@
distclean-hdr:
-rm -f src/config.h src/stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@ -289,6 +308,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdingaling_la-libdingaling.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdingaling_la-sha1.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@ -318,6 +338,13 @@ libdingaling_la-libdingaling.lo: src/libdingaling.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -c -o libdingaling_la-libdingaling.lo `test -f 'src/libdingaling.c' || echo '$(srcdir)/'`src/libdingaling.c
libdingaling_la-sha1.lo: src/sha1.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -MT libdingaling_la-sha1.lo -MD -MP -MF "$(DEPDIR)/libdingaling_la-sha1.Tpo" -c -o libdingaling_la-sha1.lo `test -f 'src/sha1.c' || echo '$(srcdir)/'`src/sha1.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdingaling_la-sha1.Tpo" "$(DEPDIR)/libdingaling_la-sha1.Plo"; else rm -f "$(DEPDIR)/libdingaling_la-sha1.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/sha1.c' object='libdingaling_la-sha1.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdingaling_la_CFLAGS) $(CFLAGS) -c -o libdingaling_la-sha1.lo `test -f 'src/sha1.c' || echo '$(srcdir)/'`src/sha1.c
mostlyclean-libtool:
-rm -f *.lo
@ -661,7 +688,7 @@ distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
distclean-hdr distclean-libtool distclean-tags
dvi: dvi-recursive
@ -713,11 +740,11 @@ uninstall-info: uninstall-info-recursive
clean-libtool clean-recursive ctags ctags-recursive dist \
dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \
distcheck distclean distclean-compile distclean-generic \
distclean-libtool distclean-recursive distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-libLTLIBRARIES \
distclean-hdr distclean-libtool distclean-recursive \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-libLTLIBRARIES \
install-library_includeHEADERS install-man install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic \

View File

@ -1947,6 +1947,8 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
ac_config_headers="$ac_config_headers src/config.h"
#AC_CONFIG_HEADER([])
# Checks for programs.
@ -3689,7 +3691,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 3692 "configure"' > conftest.$ac_ext
echo '#line 3694 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@ -5268,7 +5270,7 @@ fi
# Provide some information about the compiler.
echo "$as_me:5271:" \
echo "$as_me:5273:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@ -6366,11 +6368,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6369: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6371: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6373: \$? = $ac_status" >&5
echo "$as_me:6375: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -6628,11 +6630,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6631: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6633: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6635: \$? = $ac_status" >&5
echo "$as_me:6637: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -6690,11 +6692,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6693: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6695: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:6697: \$? = $ac_status" >&5
echo "$as_me:6699: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -8938,7 +8940,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 8941 "configure"
#line 8943 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -9036,7 +9038,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 9039 "configure"
#line 9041 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -11291,11 +11293,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11294: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11296: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:11298: \$? = $ac_status" >&5
echo "$as_me:11300: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -11353,11 +11355,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11356: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11358: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:11360: \$? = $ac_status" >&5
echo "$as_me:11362: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -12730,7 +12732,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 12733 "configure"
#line 12735 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -12828,7 +12830,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 12831 "configure"
#line 12833 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -13713,11 +13715,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13716: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13718: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:13720: \$? = $ac_status" >&5
echo "$as_me:13722: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -13775,11 +13777,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13778: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13780: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:13782: \$? = $ac_status" >&5
echo "$as_me:13784: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -15905,11 +15907,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15908: $lt_compile\"" >&5)
(eval echo "\"\$as_me:15910: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:15912: \$? = $ac_status" >&5
echo "$as_me:15914: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -16167,11 +16169,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16170: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16172: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:16174: \$? = $ac_status" >&5
echo "$as_me:16176: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -16229,11 +16231,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16232: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16234: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:16236: \$? = $ac_status" >&5
echo "$as_me:16238: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -18477,7 +18479,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18480 "configure"
#line 18482 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -18575,7 +18577,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18578 "configure"
#line 18580 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -21107,6 +21109,251 @@ done
#AC_CHECK_FUNCS([gethostname gettimeofday localtime_r memmove memset socket strcasecmp strchr strdup strncasecmp strstr])
echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
if test "${ac_cv_c_bigendian+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
# See if sys/param.h defines the BYTE_ORDER macro.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/param.h>
int
main ()
{
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
# It does; now see whether it defined to BIG_ENDIAN or not.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/param.h>
int
main ()
{
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_c_bigendian=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_c_bigendian=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
# It does not; compile a test program.
if test "$cross_compiling" = yes; then
# try to guess the endianness by grepping values into an object file
ac_cv_c_bigendian=unknown
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
int
main ()
{
_ascii (); _ebcdic ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
ac_cv_c_bigendian=yes
fi
if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
if test "$ac_cv_c_bigendian" = unknown; then
ac_cv_c_bigendian=no
else
# finding both strings is unlikely to happen, but who knows?
ac_cv_c_bigendian=unknown
fi
fi
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
/* Are we little or big endian? From Harbison&Steele. */
union
{
long l;
char c[sizeof (long)];
} u;
u.l = 1;
exit (u.c[sizeof (long) - 1] == 1);
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_c_bigendian=no
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_c_bigendian=yes
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
echo "${ECHO_T}$ac_cv_c_bigendian" >&6
case $ac_cv_c_bigendian in
yes)
cat >>confdefs.h <<\_ACEOF
#define __BYTE_ORDER __BIG_ENDIAN
_ACEOF
;;
no)
cat >>confdefs.h <<\_ACEOF
#define __BYTE_ORDER __LITTLE_ENDIAN
_ACEOF
;;
*)
{ { echo "$as_me:$LINENO: error: unknown endianness
presetting ac_cv_c_bigendian=no (or yes) will help" >&5
echo "$as_me: error: unknown endianness
presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>confdefs.h <<\_ACEOF
#define __LITTLE_ENDIAN 1234
_ACEOF
cat >>confdefs.h <<\_ACEOF
#define __BIG_ENDIAN 4321
_ACEOF
ac_config_files="$ac_config_files Makefile"
@ -21184,38 +21431,7 @@ s/^[^=]*=[ ]*$//;
}'
fi
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
# take arguments), then we branch to the quote section. Otherwise,
# look for a macro that doesn't take arguments.
cat >confdef2opt.sed <<\_ACEOF
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
t quote
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
t quote
d
: quote
s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
s,\[,\\&,g
s,\],\\&,g
s,\$,$$,g
p
_ACEOF
# We use echo to avoid assuming a particular line-breaking character.
# The extra dot is to prevent the shell from consuming trailing
# line-breaks from the sub-command output. A line-break within
# single-quotes doesn't work because, if this script is created in a
# platform that uses two characters for line-breaks (e.g., DOS), tr
# would break.
ac_LF_and_DOT=`echo; echo .`
DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
rm -f confdef2opt.sed
DEFS=-DHAVE_CONFIG_H
ac_libobjs=
ac_ltlibobjs=
@ -21570,10 +21786,15 @@ Usage: $0 [OPTIONS] [FILE]...
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration files:
$config_files
Configuration headers:
$config_headers
Configuration commands:
$config_commands
@ -21694,6 +21915,7 @@ do
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };;
@ -21706,6 +21928,7 @@ done
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
fi
@ -22085,6 +22308,251 @@ done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
#
# CONFIG_HEADER section.
#
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
# Do quote $f, to prevent DOS paths from being IFS'd.
echo "$f";;
*) # Relative
if test -f "$f"; then
# Build tree
echo "$f"
elif test -f "$srcdir/$f"; then
# Source tree
echo "$srcdir/$f"
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
_ACEOF
# Transform confdefs.h into two sed scripts, `conftest.defines' and
# `conftest.undefs', that substitutes the proper values into
# config.h.in to produce config.h. The first handles `#define'
# templates, and the second `#undef' templates.
# And first: Protect against being on the right side of a sed subst in
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
# Using a here document instead of a string reduces the quoting nightmare.
# Putting comments in sed scripts is not portable.
#
# `end' is used to avoid that the second main sed command (meant for
# 0-ary CPP macros) applies to n-ary macro definitions.
# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\_ACEOF
s/[\\&,]/\\&/g
s,[\\$`],\\&,g
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
t end
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
: end
_ACEOF
# If some macros were called several times there might be several times
# the same #defines, which is useless. Nevertheless, we may not want to
# sort them, since we want the *last* AC-DEFINE to be honored.
uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
rm -f confdef2sed.sed
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >>conftest.undefs <<\_ACEOF
s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
_ACEOF
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.defines >/dev/null
do
# Write a limited-size here document to $tmp/defines.sed.
echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#define' lines.
echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/defines.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
rm -f conftest.defines
mv conftest.tail conftest.defines
done
rm -f conftest.defines
echo ' fi # grep' >>$CONFIG_STATUS
echo >>$CONFIG_STATUS
# Break up conftest.undefs because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.undefs >/dev/null
do
# Write a limited-size here document to $tmp/undefs.sed.
echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#undef'
echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/undefs.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
rm -f conftest.undefs
mv conftest.tail conftest.undefs
done
rm -f conftest.undefs
cat >>$CONFIG_STATUS <<\_ACEOF
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
echo "/* Generated by configure. */" >$tmp/config.h
else
echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
rm -f $ac_file
mv $tmp/config.h $ac_file
fi
else
cat $tmp/config.h
rm -f $tmp/config.h
fi
# Compute $ac_file's index in $config_headers.
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$ac_file | $ac_file:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X$ac_file : 'X\(//\)[^/]' \| \
X$ac_file : 'X\(//\)$' \| \
X$ac_file : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X$ac_file |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`/stamp-h$_am_stamp_count
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
#
# CONFIG_COMMANDS section.
#

View File

@ -5,6 +5,7 @@
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(libdingaling,0.1)
AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([src/config.h])
#AC_CONFIG_HEADER([])
# Checks for programs.
@ -32,6 +33,10 @@ AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
#AC_CHECK_FUNCS([gethostname gettimeofday localtime_r memmove memset socket strcasecmp strchr strdup strncasecmp strstr])
AC_C_BIGENDIAN(AC_DEFINE([__BYTE_ORDER],__BIG_ENDIAN,[Big Endian]),AC_DEFINE([__BYTE_ORDER],__LITTLE_ENDIAN,[Little Endian]))
AC_DEFINE([__LITTLE_ENDIAN],1234,[for the places where it is not defined])
AC_DEFINE([__BIG_ENDIAN],4321,[for the places where it is not defined])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@ -60,6 +60,7 @@
#include "ldl_compat.h"
#include "libdingaling.h"
#include "sha1.h"
#define microsleep(x) apr_sleep(x * 1000)
@ -89,6 +90,12 @@ struct ldl_buffer {
int hit;
};
typedef enum {
CS_NEW,
CS_START,
CS_CONNECTED
} ldl_handle_state_t;
struct ldl_handle {
iksparser *parser;
iksid *acc;
@ -116,6 +123,7 @@ struct ldl_handle {
apr_pool_t *pool;
void *private_info;
FILE *log_stream;
ldl_handle_state_t state;
};
struct ldl_session {
@ -125,6 +133,7 @@ struct ldl_session {
char *initiator;
char *them;
char *ip;
char *login;
ldl_payload_t payloads[LDL_MAX_PAYLOADS];
unsigned int payload_len;
ldl_candidate_t candidates[LDL_MAX_CANDIDATES];
@ -193,7 +202,7 @@ char *ldl_session_get_id(ldl_session_t *session)
void ldl_session_send_msg(ldl_session_t *session, char *subject, char *body)
{
ldl_handle_send_msg(session->handle, session->them, subject, body);
ldl_handle_send_msg(session->handle, session->login, session->them, subject, body);
}
ldl_status ldl_session_destroy(ldl_session_t **session_p)
@ -235,14 +244,21 @@ ldl_status ldl_session_create(ldl_session_t **session_p, ldl_handle_t *handle, c
*session_p = NULL;
return LDL_STATUS_MEMERR;
}
memset(session, 0, sizeof(ldl_session_t));
apr_pool_create(&session->pool, globals.memory_pool);
session->id = apr_pstrdup(session->pool, id);
session->them = apr_pstrdup(session->pool, them);
if (me) {
session->initiator = apr_pstrdup(session->pool, me);
//if (me) {
//session->initiator = apr_pstrdup(session->pool, them);
//}
if (ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
session->login = apr_pstrdup(session->pool, me);
} else {
session->login = apr_pstrdup(session->pool, handle->login);
}
apr_hash_set(handle->sessions, session->id, APR_HASH_KEY_STRING, session);
apr_hash_set(handle->sessions, session->them, APR_HASH_KEY_STRING, session);
session->handle = handle;
@ -259,7 +275,7 @@ ldl_status ldl_session_create(ldl_session_t **session_p, ldl_handle_t *handle, c
return LDL_STATUS_SUCCESS;
}
static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from, iks *xml, char *xtype)
static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from, char *to, iks *xml, char *xtype)
{
ldl_session_t *session = NULL;
ldl_signal_t signal = LDL_SIGNAL_NONE;
@ -267,7 +283,7 @@ static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from,
char *msg = NULL;
if (!(session = apr_hash_get(handle->sessions, id, APR_HASH_KEY_STRING))) {
ldl_session_create(&session, handle, id, from, initiator);
ldl_session_create(&session, handle, id, from, to);
if (!session) {
return LDL_STATUS_MEMERR;
}
@ -433,7 +449,7 @@ static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from,
}
if (handle->session_callback && signal) {
handle->session_callback(handle, session, signal, from, id, msg);
handle->session_callback(handle, session, signal, to, from, id, msg);
}
return LDL_STATUS_SUCCESS;
@ -441,10 +457,208 @@ static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from,
const char *marker = "TRUE";
static int on_disco_info(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
if (pak->subtype == IKS_TYPE_RESULT) {
if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
char *from = iks_find_attrib(pak->x, "from");
char id[1024];
char *resource;
struct ldl_buffer *buffer;
size_t x;
if (!apr_hash_get(handle->sub_hash, from, APR_HASH_KEY_STRING)) {
iks *msg;
apr_hash_set(handle->sub_hash, apr_pstrdup(handle->pool, from), APR_HASH_KEY_STRING, &marker);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBED, from, "Ding A Ling....");
apr_queue_push(handle->queue, msg);
}
apr_cpystrn(id, from, sizeof(id));
if ((resource = strchr(id, '/'))) {
*resource++ = '\0';
}
if (resource) {
for (x = 0; x < strlen(resource); x++) {
resource[x] = (char)tolower((int)resource[x]);
}
}
if (resource && strstr(resource, "talk") && (buffer = apr_hash_get(handle->probe_hash, id, APR_HASH_KEY_STRING))) {
apr_cpystrn(buffer->buf, from, buffer->len);
fflush(stderr);
buffer->hit = 1;
}
}
return IKS_FILTER_EAT;
}
if (pak->subtype == IKS_TYPE_GET) {
iks *iq, *query, *tag;
uint8_t send = 0;
if ((iq = iks_new("iq"))) {
do {
iks_insert_attrib(iq, "from", handle->login);
iks_insert_attrib(iq, "to", pak->from->full);
iks_insert_attrib(iq, "id", pak->id);
iks_insert_attrib(iq, "type", "result");
if (!(query = iks_insert (iq, "query"))) {
break;
}
iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
if (!(tag = iks_insert (query, "identity"))) {
break;
}
iks_insert_attrib(tag, "category", "client");
iks_insert_attrib(tag, "type", "voice");
iks_insert_attrib(tag, "name", "LibDingaLing");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "http://jabber.org/protocol/disco#info");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "http://www.google.com/xmpp/protocol/voice/v1");
iks_send(handle->parser, iq);
send = 1;
} while (0);
iks_delete(iq);
}
if (!send) {
globals.logger(DL_LOG_DEBUG, "Memory Error!\n");
}
}
return IKS_FILTER_EAT;
}
static int on_component_disco_info(void *user_data, ikspak *pak)
{
char *node = iks_find_attrib(pak->query, "node");
ldl_handle_t *handle = user_data;
if (pak->subtype == IKS_TYPE_RESULT) {
globals.logger(DL_LOG_DEBUG, "FixME!!! node=[%s]\n", node?node:"");
} else if (pak->subtype == IKS_TYPE_GET) {
// if (ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
if (node) {
} else {
iks *iq, *query, *tag;
uint8_t send = 0;
if ((iq = iks_new("iq"))) {
do {
iks_insert_attrib(iq, "from", handle->login);
iks_insert_attrib(iq, "to", pak->from->full);
iks_insert_attrib(iq, "id", pak->id);
iks_insert_attrib(iq, "type", "result");
if (!(query = iks_insert (iq, "query"))) {
break;
}
iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
if (!(tag = iks_insert (query, "identity"))) {
break;
}
iks_insert_attrib(tag, "category", "gateway");
iks_insert_attrib(tag, "type", "voice");
iks_insert_attrib(tag, "name", "LibDingaLing");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "http://jabber.org/protocol/disco");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "jabber:iq:register");
/*
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "http://jabber.org/protocol/commands");
*/
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "jabber:iq:gateway");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "jabber:iq:version");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "vcard-temp");
if (!(tag = iks_insert (query, "feature"))) {
break;
}
iks_insert_attrib(tag, "var", "jabber:iq:search");
iks_send(handle->parser, iq);
send = 1;
} while (0);
iks_delete(iq);
}
if (!send) {
globals.logger(DL_LOG_DEBUG, "Memory Error!\n");
}
}
}
return IKS_FILTER_EAT;
}
static int on_disco_items(void *user_data, ikspak *pak)
{
globals.logger(DL_LOG_DEBUG, "FixME!!!\n");
return IKS_FILTER_EAT;
}
static int on_disco_reg_in(void *user_data, ikspak *pak)
{
globals.logger(DL_LOG_DEBUG, "FixME!!!\n");
return IKS_FILTER_EAT;
}
static int on_disco_reg_out(void *user_data, ikspak *pak)
{
globals.logger(DL_LOG_DEBUG, "FixME!!!\n");
return IKS_FILTER_EAT;
}
static int on_presence(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
char *from = iks_find_attrib(pak->x, "from");
char *to = iks_find_attrib(pak->x, "to");
char *type = iks_find_attrib(pak->x, "type");
char *show = iks_find_cdata(pak->x, "show");
char *status = iks_find_cdata(pak->x, "status");
@ -454,6 +668,7 @@ static int on_presence(void *user_data, ikspak *pak)
size_t x;
ldl_signal_t signal;
if (type && !strcasecmp(type, "unavailable")) {
signal = LDL_SIGNAL_PRESENCE_OUT;
} else {
@ -464,9 +679,7 @@ static int on_presence(void *user_data, ikspak *pak)
status = type;
}
if (handle->session_callback) {
handle->session_callback(handle, NULL, signal, from, status ? status : "n/a", show ? show : "n/a");
}
if (!apr_hash_get(handle->sub_hash, from, APR_HASH_KEY_STRING)) {
iks *msg;
@ -491,20 +704,104 @@ static int on_presence(void *user_data, ikspak *pak)
fflush(stderr);
buffer->hit = 1;
}
if (!type || (type && strcasecmp(type, "probe"))) {
if (handle->session_callback) {
handle->session_callback(handle, NULL, signal, to, from, status ? status : "n/a", show ? show : "n/a");
}
}
return IKS_FILTER_EAT;
}
static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
{
iks *pres;
char buf[512];
iks *tag;
if (!strchr(from, '/')) {
snprintf(buf, sizeof(buf), "%s/talk", from);
from = buf;
}
if ((pres = iks_new("presence"))) {
iks_insert_attrib(pres, "xmlns", "jabber:client");
if (from) {
iks_insert_attrib(pres, "from", from);
}
if (to) {
iks_insert_attrib(pres, "to", to);
}
if (type) {
iks_insert_attrib(pres, "type", type);
}
if (message) {
if ((tag = iks_insert (pres, "status"))) {
iks_insert_cdata(tag, message ? message : "", 0);
if ((tag = iks_insert(pres, "c"))) {
iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
iks_insert_attrib(tag, "ver", "1.0.0.1");
iks_insert_attrib(tag, "ext", "sidebar voice-v1");
iks_insert_attrib(tag, "client", "libdingaling2");
iks_insert_attrib(tag, "xmlns", "http://jabber.org/protocol/caps");
}
}
}
apr_queue_push(handle->queue, pres);
}
}
static void do_roster(ldl_handle_t *handle)
{
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_ROSTER, NULL, handle->login, NULL, NULL);
}
}
static int on_unsubscribe(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
char *from = iks_find_attrib(pak->x, "from");
char *to = iks_find_attrib(pak->x, "to");
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_SUBSCRIBE, to, from, NULL, NULL);
}
return IKS_FILTER_EAT;
}
static int on_subscribe(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
char *from = iks_find_attrib(pak->x, "from");
char *to = iks_find_attrib(pak->x, "to");
iks *msg = iks_make_s10n (IKS_TYPE_SUBSCRIBED, from, "Ding A Ling....");
if (to && ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
iks_insert_attrib(msg, "from", to);
}
apr_queue_push(handle->queue, msg);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBE, from, "Ding A Ling....");
if (to && ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
iks_insert_attrib(msg, "from", to);
}
apr_queue_push(handle->queue, msg);
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_SUBSCRIBE, to, from, NULL, NULL);
}
return IKS_FILTER_EAT;
}
@ -526,7 +823,7 @@ static int on_commands(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
char *from = iks_find_attrib(pak->x, "from");
//char *to = iks_find_attrib(pak->x, "to");
char *to = iks_find_attrib(pak->x, "to");
char *iqid = iks_find_attrib(pak->x, "id");
char *type = iks_find_attrib(pak->x, "type");
uint8_t is_result = strcasecmp(type, "result") ? 0 : 1;
@ -540,9 +837,10 @@ static int on_commands(void *user_data, ikspak *pak)
if (!strcasecmp(iks_name(tag), "bind")) {
char *jid = iks_find_cdata(tag, "jid");
char *resource = strchr(jid, '/');
iks *iq, *x;
//iks *iq, *x;
handle->acc->resource = apr_pstrdup(handle->pool, resource);
handle->login = apr_pstrdup(handle->pool, jid);
#if 0
if ((iq = iks_new("iq"))) {
iks_insert_attrib(iq, "type", "get");
iks_insert_attrib(iq, "id", "roster");
@ -555,6 +853,7 @@ static int on_commands(void *user_data, ikspak *pak)
iks_delete(iq);
break;
}
#endif
}
tag = iks_next_tag(tag);
}
@ -579,10 +878,11 @@ static int on_commands(void *user_data, ikspak *pak)
if (!strcasecmp(name, "session")) {
char *id = iks_find_attrib(xml, "id");
//printf("SESSION type=%s name=%s id=%s\n", type, name, id);
if (parse_session_code(handle, id, from, xml, strcasecmp(type, "error") ? NULL : type) == LDL_STATUS_SUCCESS) {
if (parse_session_code(handle, id, from, to, xml, strcasecmp(type, "error") ? NULL : type) == LDL_STATUS_SUCCESS) {
iks *reply;
reply = iks_make_iq(IKS_TYPE_RESULT, NULL);
iks_insert_attrib(reply, "to", from);
iks_insert_attrib(reply, "from", to);
iks_insert_attrib(reply, "id", iqid);
apr_queue_push(handle->queue, reply);
}
@ -644,7 +944,88 @@ static int b64encode(unsigned char *in, uint32_t ilen, unsigned char *out, uint3
return 0;
}
static int on_stream(ldl_handle_t *handle, int type, iks * node)
static void sha1_hash(char *out, char *in)
{
sha_context_t sha;
char *p;
int x;
unsigned char digest[20];
SHA1Init(&sha);
SHA1Update(&sha, (unsigned char *) in, strlen(in));
SHA1Final(digest, &sha);
p = out;
for (x = 0; x < 20; x++) {
p += sprintf(p, "%2.2x", digest[x]);
}
}
static int on_stream_component(ldl_handle_t *handle, int type, iks *node)
{
ikspak *pak = iks_packet(node);
switch (type) {
case IKS_NODE_START:
if (handle->state == CS_NEW) {
char secret[256];
char hash[256];
char handshake[512];
snprintf(secret, sizeof(secret), "%s%s", pak->id, handle->password);
sha1_hash(hash, secret);
snprintf(handshake, sizeof(handshake), "<handshake>%s</handshake>", hash);
iks_send_raw(handle->parser, handshake);
handle->state = CS_START;
if (iks_recv(handle->parser, 1) == 2) {
handle->state = CS_CONNECTED;
if (!ldl_test_flag(handle, LDL_FLAG_AUTHORIZED)) {
ldl_set_flag_locked(handle, LDL_FLAG_READY);
do_roster(handle);
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "user", "core", "Login Success", handle->login);
}
globals.logger(DL_LOG_DEBUG, "XMPP authenticated\n");
ldl_set_flag_locked(handle, LDL_FLAG_AUTHORIZED);
}
} else {
globals.logger(DL_LOG_ERR, "LOGIN ERROR!\n");
handle->state = CS_NEW;
}
break;
}
break;
case IKS_NODE_NORMAL:
break;
case IKS_NODE_ERROR:
globals.logger(DL_LOG_ERR, "NODE ERROR!\n");
return IKS_HOOK;
case IKS_NODE_STOP:
globals.logger(DL_LOG_ERR, "DISCONNECTED!\n");
return IKS_HOOK;
}
pak = iks_packet(node);
iks_filter_packet(handle->filter, pak);
if (handle->job_done == 1) {
return IKS_HOOK;
}
if (node) {
iks_delete(node);
}
return IKS_OK;
}
static int on_stream(ldl_handle_t *handle, int type, iks *node)
{
handle->counter = opt_timeout;
@ -708,20 +1089,20 @@ static int on_stream(ldl_handle_t *handle, int type, iks * node)
} else if (strcmp("failure", iks_name(node)) == 0) {
globals.logger(DL_LOG_DEBUG, "sasl authentication failed\n");
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_FAILURE, "core", "Login Failure", handle->login);
handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_FAILURE, "user", "core", "Login Failure", handle->login);
}
} else if (strcmp("success", iks_name(node)) == 0) {
globals.logger(DL_LOG_DEBUG, "XMPP server connected\n");
iks_send_header(handle->parser, handle->acc->server);
ldl_set_flag_locked(handle, LDL_FLAG_CONNECTED);
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_CONNECTED, "core", "Server Connected", handle->login);
handle->session_callback(handle, NULL, LDL_SIGNAL_CONNECTED, "user", "core", "Server Connected", handle->login);
}
} else {
ikspak *pak;
if (!ldl_test_flag(handle, LDL_FLAG_AUTHORIZED)) {
if (handle->session_callback) {
handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "core", "Login Success", handle->login);
handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "user", "core", "Login Success", handle->login);
}
globals.logger(DL_LOG_DEBUG, "XMPP authenticated\n");
ldl_set_flag_locked(handle, LDL_FLAG_AUTHORIZED);
@ -754,6 +1135,7 @@ static int on_stream(ldl_handle_t *handle, int type, iks * node)
static int on_msg(void *user_data, ikspak *pak)
{
char *cmd = iks_find_cdata(pak->x, "body");
char *to = iks_find_attrib(pak->x, "to");
char *from = iks_find_attrib(pak->x, "from");
char *subject = iks_find_attrib(pak->x, "subject");
ldl_handle_t *handle = user_data;
@ -764,7 +1146,7 @@ static int on_msg(void *user_data, ikspak *pak)
}
if (handle->session_callback) {
handle->session_callback(handle, session, LDL_SIGNAL_MSG, from, subject ? subject : "N/A", cmd);
handle->session_callback(handle, session, LDL_SIGNAL_MSG, to, from, subject ? subject : "N/A", cmd);
}
return 0;
@ -789,18 +1171,13 @@ static void on_log(ldl_handle_t *handle, const char *data, size_t size, int is_i
fprintf(stderr, "[%s]\n", data);
}
static void j_setup_filter(ldl_handle_t *handle, char *login)
static void j_setup_filter(ldl_handle_t *handle)
{
if (handle->filter) {
iks_filter_delete(handle->filter);
}
handle->filter = iks_filter_new();
/*
iks_filter_add_rule(handle->filter, on_msg, 0,
IKS_RULE_TYPE, IKS_PAK_MESSAGE,
IKS_RULE_SUBTYPE, IKS_TYPE_CHAT, IKS_RULE_FROM, login, IKS_RULE_DONE);
*/
iks_filter_add_rule(handle->filter, on_msg, handle, IKS_RULE_TYPE, IKS_PAK_MESSAGE, IKS_RULE_SUBTYPE, IKS_TYPE_CHAT, IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_result, handle,
@ -832,9 +1209,31 @@ static void j_setup_filter(ldl_handle_t *handle, char *login)
IKS_RULE_SUBTYPE, IKS_TYPE_SUBSCRIBE,
IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_unsubscribe, handle,
IKS_RULE_TYPE, IKS_PAK_S10N,
IKS_RULE_SUBTYPE, IKS_TYPE_UNSUBSCRIBE,
IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_error, handle,
IKS_RULE_TYPE, IKS_PAK_IQ,
IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, IKS_RULE_ID, "auth", IKS_RULE_DONE);
if (ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
iks_filter_add_rule(handle->filter, on_component_disco_info, handle,
IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_disco_items, handle,
IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_disco_reg_in, handle,
IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
iks_filter_add_rule(handle->filter, on_disco_reg_out, handle,
IKS_RULE_SUBTYPE, IKS_TYPE_SET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
} else {
iks_filter_add_rule(handle->filter, on_disco_info, handle,
IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
}
}
static void ldl_flush_queue(ldl_handle_t *handle)
@ -928,26 +1327,35 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
{
while (ldl_test_flag(handle, LDL_FLAG_RUNNING)) {
int e;
char tmp[512], *sl;
handle->parser = iks_stream_new(ldl_test_flag(handle, LDL_FLAG_COMPONENT) ? IKS_NS_COMPONENT : IKS_NS_CLIENT,
handle,
(iksStreamHook *) (ldl_test_flag(handle, LDL_FLAG_COMPONENT) ? on_stream_component : on_stream));
handle->parser = iks_stream_new(IKS_NS_CLIENT, handle, (iksStreamHook *) on_stream);
if (globals.debug) {
iks_set_log_hook(handle->parser, (iksLogHook *) on_log);
}
handle->acc = iks_id_new(iks_parser_stack(handle->parser), jabber_id);
if (NULL == handle->acc->resource) {
strncpy(tmp, jabber_id, sizeof(tmp)-1);
sl = strchr(tmp, '/');
if (!sl && !ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
/* user gave no resource name, use the default */
char tmp[512];
sprintf(tmp, "%s@%s/%s", handle->acc->user, handle->acc->server, "dingaling");
handle->acc = iks_id_new(iks_parser_stack(handle->parser), tmp);
snprintf(tmp + strlen(tmp), sizeof(tmp) - strlen(tmp), "/%s", "talk");
} else if (sl && ldl_test_flag(handle, LDL_FLAG_COMPONENT)) {
*sl = '\0';
}
handle->acc = iks_id_new(iks_parser_stack(handle->parser), tmp);
handle->password = pass;
j_setup_filter(handle, "fixme");
j_setup_filter(handle);
e = iks_connect_via(handle->parser,
handle->server ? handle->server : handle->acc->server,
handle->port ? handle->port : IKS_JABBER_PORT,
//handle->server ? handle->server : handle->acc->server);
handle->acc->server);
switch (e) {
@ -1040,7 +1448,7 @@ static ldl_status new_session_iq(ldl_session_t *session, iks **iqp, iks **sessp,
snprintf(idbuf, sizeof(idbuf), "%u", myid);
iq = iks_new("iq");
iks_insert_attrib(iq, "xmlns", "jabber:client");
iks_insert_attrib(iq, "from", session->handle->login);
iks_insert_attrib(iq, "from", session->login);
iks_insert_attrib(iq, "to", session->them);
iks_insert_attrib(iq, "type", "set");
iks_insert_attrib(iq, "id", idbuf);
@ -1092,6 +1500,11 @@ char *ldl_session_get_caller(ldl_session_t *session)
return session->them;
}
char *ldl_session_get_callee(ldl_session_t *session)
{
return session->login;
}
void ldl_session_set_ip(ldl_session_t *session, char *ip)
{
session->ip = apr_pstrdup(session->pool, ip);
@ -1123,7 +1536,7 @@ void ldl_session_accept_candidate(ldl_session_t *session, ldl_candidate_t *candi
iq = iks_new("iq");
iks_insert_attrib(iq, "type", "set");
iks_insert_attrib(iq, "id", idbuf);
iks_insert_attrib(iq, "from", session->handle->login);
iks_insert_attrib(iq, "from", session->login);
iks_insert_attrib(iq, "to", session->them);
sess = iks_insert (iq, "session");
iks_insert_attrib(sess, "xmlns", "http://www.google.com/session");
@ -1142,7 +1555,12 @@ void *ldl_handle_get_private(ldl_handle_t *handle)
return handle->private_info;
}
void ldl_handle_send_msg(ldl_handle_t *handle, char *to, char *subject, char *body)
void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
{
do_presence(handle, from, to, type, message);
}
void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, char *subject, char *body)
{
iks *msg;
@ -1153,6 +1571,12 @@ void ldl_handle_send_msg(ldl_handle_t *handle, char *to, char *subject, char *bo
msg = iks_make_msg(IKS_TYPE_NONE, to, body);
iks_insert_attrib(msg, "type", "chat");
if (!from) {
from = handle->login;
}
iks_insert_attrib(msg, "from", from);
if (subject) {
iks_insert_attrib(msg, "subject", subject);
}
@ -1235,7 +1659,7 @@ unsigned int ldl_session_candidates(ldl_session_t *session,
return id;
}
char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *buf, unsigned int len)
char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *from, char *buf, unsigned int len)
{
iks *pres, *msg;
char *lid = NULL;
@ -1251,11 +1675,13 @@ char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *buf, unsigned int l
pres = iks_new("presence");
iks_insert_attrib(pres, "type", "probe");
iks_insert_attrib(pres, "from", from);
iks_insert_attrib(pres, "to", id);
apr_hash_set(handle->probe_hash, id, APR_HASH_KEY_STRING, &buffer);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBE, id, notice);
iks_insert_attrib(pres, "from", from);
apr_queue_push(handle->queue, msg);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBED, id, notice);
apr_queue_push(handle->queue, msg);
@ -1263,6 +1689,75 @@ char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *buf, unsigned int l
//schedule_packet(handle, next_id(), pres, LDL_RETRY);
started = apr_time_now();
for(;;) {
elapsed = (unsigned int)((apr_time_now() - started) / 1000);
if (elapsed > 5000 && ! again) {
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBE, id, notice);
iks_insert_attrib(pres, "from", from);
apr_queue_push(handle->queue, msg);
again++;
}
if (elapsed > 10000) {
break;
}
if (buffer.hit) {
lid = buffer.buf;
break;
}
ldl_yield(1000);
}
apr_hash_set(handle->probe_hash, id, APR_HASH_KEY_STRING, NULL);
return lid;
}
char *ldl_handle_disco(ldl_handle_t *handle, char *id, char *from, char *buf, unsigned int len)
{
iks *iq, *query, *msg;
char *lid = NULL;
struct ldl_buffer buffer;
apr_time_t started;
unsigned int elapsed;
char *notice = "Call Me!";
int again = 0;
unsigned int myid;
char idbuf[80];
myid = next_id();
snprintf(idbuf, sizeof(idbuf), "%u", myid);
buffer.buf = buf;
buffer.len = len;
buffer.hit = 0;
if ((iq = iks_new("iq"))) {
if ((query = iks_insert(iq, "query"))) {
iks_insert_attrib(iq, "type", "get");
iks_insert_attrib(iq, "to", id);
iks_insert_attrib(iq,"from", from);
iks_insert_attrib(iq, "id", idbuf);
iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
} else {
iks_delete(iq);
globals.logger(DL_LOG_DEBUG, "Memory ERROR!\n");
return NULL;
}
} else {
globals.logger(DL_LOG_DEBUG, "Memory ERROR!\n");
return NULL;
}
apr_hash_set(handle->probe_hash, id, APR_HASH_KEY_STRING, &buffer);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBE, id, notice);
apr_queue_push(handle->queue, msg);
msg = iks_make_s10n (IKS_TYPE_SUBSCRIBED, id, notice);
apr_queue_push(handle->queue, msg);
apr_queue_push(handle->queue, iq);
//schedule_packet(handle, next_id(), pres, LDL_RETRY);
started = apr_time_now();
for(;;) {
elapsed = (unsigned int)((apr_time_now() - started) / 1000);

View File

@ -50,6 +50,7 @@ extern "C" {
#define LDL_MAX_CANDIDATES 10
#define LDL_MAX_PAYLOADS 50
#define LDL_RETRY 3
#define IKS_NS_COMPONENT "jabber:component:accept"
/*! \brief A structure to store a jingle candidate */
struct ldl_candidate {
@ -105,13 +106,14 @@ typedef enum {
LDL_FLAG_AUTHORIZED = (1 << 2),
LDL_FLAG_READY = (1 << 3),
LDL_FLAG_CONNECTED = (1 << 4),
LDL_FLAG_QUEUE_RUNNING = (1 << 5),
LDL_FLAG_QUEUE_RUNNING = (1 << 5)
} ldl_flag_t;
typedef enum {
LDL_FLAG_TLS = (1 << 10),
LDL_FLAG_SASL_PLAIN = (1 << 11),
LDL_FLAG_SASL_MD5 = (1 << 12)
LDL_FLAG_SASL_MD5 = (1 << 12),
LDL_FLAG_COMPONENT = (1 << 13),
} ldl_user_flag_t;
typedef enum {
@ -121,6 +123,9 @@ typedef enum {
LDL_SIGNAL_MSG,
LDL_SIGNAL_PRESENCE_IN,
LDL_SIGNAL_PRESENCE_OUT,
LDL_SIGNAL_ROSTER,
LDL_SIGNAL_SUBSCRIBE,
LDL_SIGNAL_UNSUBSCRIBE,
LDL_SIGNAL_TERMINATE,
LDL_SIGNAL_ERROR,
LDL_SIGNAL_LOGIN_SUCCESS,
@ -156,7 +161,7 @@ typedef enum {
#define DL_LOG_EMERG DL_PRE, 0
typedef ldl_status (*ldl_loop_callback_t)(ldl_handle_t *);
typedef ldl_status (*ldl_session_callback_t)(ldl_handle_t *, ldl_session_t *, ldl_signal_t, char *, char *, char *);
typedef ldl_status (*ldl_session_callback_t)(ldl_handle_t *, ldl_session_t *, ldl_signal_t, char *, char *, char *, char *);
typedef ldl_status (*ldl_response_callback_t)(ldl_handle_t *, char *);
typedef void (*ldl_logger_t)(char *file, const char *func, int line, int level, char *fmt, ...);
@ -265,6 +270,13 @@ char *ldl_session_get_id(ldl_session_t *session);
*/
char *ldl_session_get_caller(ldl_session_t *session);
/*!
\brief Get the callee name of a session
\param session the session to get the callee from
\return the callee name
*/
char *ldl_session_get_callee(ldl_session_t *session);
/*!
\brief Set the ip of a session
\param session the session to set the ip on
@ -310,11 +322,23 @@ void ldl_global_set_logger(ldl_logger_t logger);
\brief Perform a probe on a given id to resolve the proper Jingle Resource
\param handle the connection handle to use.
\param id the id to probe
\param from the from string
\param buf a string to store the result
\param len the size in bytes of the string
\return a pointer to buf if a successful lookup was made otherwise NULL
*/
char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *buf, unsigned int len);
char *ldl_handle_probe(ldl_handle_t *handle, char *id, char *from, char *buf, unsigned int len);
/*!
\brief Perform a discovery on a given id to resolve the proper Jingle Resource
\param handle the connection handle to use.
\param id the id to probe
\param from the from string
\param buf a string to store the result
\param len the size in bytes of the string
\return a pointer to buf if a successful lookup was made otherwise NULL
*/
char *ldl_handle_disco(ldl_handle_t *handle, char *id, char *from, char *buf, unsigned int len);
/*!
\brief Signal a termination request on a given session
@ -339,14 +363,25 @@ void *ldl_handle_get_private(ldl_handle_t *handle);
*/
void ldl_session_send_msg(ldl_session_t *session, char *subject, char *body);
/*!
\brief Send a presence notification to a target
\param handle the handle to send with
\param from the from address
\param to the to address
\param type the type of presence
\param message a status message
*/
void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message);
/*!
\brief Send a message
\param handle the conection handle
\param from the message sender
\param to the message recipiant
\param subject optional subject
\param body body of the message
*/
void ldl_handle_send_msg(ldl_handle_t *handle, char *to, char *subject, char *body);
void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, char *subject, char *body);
/*!
\brief Offer candidates to a potential session

View File

@ -0,0 +1,203 @@
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libDingaLing XMPP Jingle Library
*
* The Initial Developer of the Original Code is
* Steve Reid <steve@edmweb.com>
*
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Steve Reid <steve@edmweb.com>
*
* sha1.h
*
*/
/*! \file sha1.c
\brief SHA1
*/
/*
ORIGINAL HEADERS
----------------------------------------------------------------------------------------------
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "sha1.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(sha_context_t* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(sha_context_t* context, unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], sha_context_t* context)
{
unsigned long i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}

View File

@ -0,0 +1,58 @@
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libDingaLing XMPP Jingle Library
*
* The Initial Developer of the Original Code is
* Steve Reid <steve@edmweb.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Steve Reid <steve@edmweb.com>
*
* sha1.h
*
*/
/*! \file sha1.h
\brief SHA1
*/
#ifndef __SHA1_H
#define __SHA1_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __STUPIDFORMATBUG__
}
#endif
typedef struct {
unsigned long state[5];
unsigned long count[2];
unsigned char buffer[64];
} sha_context_t;
void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
void SHA1Init(sha_context_t* context);
void SHA1Update(sha_context_t* context, unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[20], sha_context_t* context);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -841,6 +841,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer)
\brief Initialize a codec handle
\param codec the handle to initilize
\param codec_name the name of the codec module to use
\param fmtp codec parameters to send
\param rate the desired rate (0 for any)
\param ms the desired number of milliseconds (0 for any)
\param channels the desired number of channels (0 for any)

View File

@ -97,6 +97,8 @@ struct switch_event {
void *bind_user_data;
/*! user data from the event sender */
void *event_user_data;
/*! unique key */
unsigned long key;
struct switch_event *next;
};

View File

@ -72,6 +72,7 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void);
\param ms_per_packet time in microseconds per packet
\param flags flags to control behaviour
\param crypto_key optional crypto key
\param timer_name timer interface to use
\param err a pointer to resolve error messages
\param pool a memory pool to use for the session
\return the new RTP session or NULL on failure
@ -98,6 +99,7 @@ SWITCH_DECLARE(switch_status_t)switch_rtp_create(switch_rtp_t **new_rtp_session,
\param ms_per_packet time in microseconds per packet
\param flags flags to control behaviour
\param crypto_key optional crypto key
\param timer_name timer interface to use
\param err a pointer to resolve error messages
\param pool a memory pool to use for the session
\return the new RTP session or NULL on failure

View File

@ -659,6 +659,7 @@ typedef enum {
SWITCH_EVENT_MESSAGE,
SWITCH_EVENT_PRESENCE_IN,
SWITCH_EVENT_PRESENCE_OUT,
SWITCH_EVENT_ROSTER,
SWITCH_EVENT_CODEC,
SWITCH_EVENT_BACKGROUND_JOB,
SWITCH_EVENT_ALL

View File

@ -34,7 +34,7 @@
#define DL_CAND_WAIT 10000000
#define DL_CAND_INITIAL_WAIT 2000000
#define JINGLE_KEY 1
#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
@ -44,6 +44,13 @@ static const char modname[] = "mod_dingaling";
static switch_memory_pool_t *module_pool = NULL;
static char sub_sql[] =
"CREATE TABLE subscriptions (\n"
" sub_from VARCHAR(255),\n"
" sub_to VARCHAR(255)\n"
");\n";
typedef enum {
TFLAG_IO = (1 << 0),
TFLAG_INBOUND = (1 << 1),
@ -104,6 +111,8 @@ struct mdl_profile {
char *exten;
char *context;
char *timer_name;
char *dbname;
switch_mutex_t *mutex;
ldl_handle_t *handle;
uint32_t flags;
uint32_t user_flags;
@ -173,11 +182,207 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg);
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *to, char *from, char *subject, char *msg);
static ldl_status handle_response(ldl_handle_t *handle, char *id);
static switch_status_t load_config(void);
static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct mdl_profile *profile = (struct mdl_profile *) pArg;
char *sub_from = argv[0];
char *sub_to = argv[1];
char *type = argv[2];
char *show = argv[3];
if (switch_strlen_zero(type)) {
type = NULL;
} else if (!strcasecmp(type, "unavailable")) {
show = NULL;
}
ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, show);
return 0;
}
static int rost_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct mdl_profile *profile = (struct mdl_profile *) pArg;
char *sub_from = argv[0];
char *sub_to = argv[1];
char *show = argv[2];
ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show);
return 0;
}
static void pres_event_handler(switch_event_t *event)
{
struct mdl_profile *profile = NULL;
switch_hash_index_t *hi;
void *val;
char *from = switch_event_get_header(event, "from");
char *status= switch_event_get_header(event, "status");
char *show= switch_event_get_header(event, "show");
char *type = NULL;
char *sql;
switch_core_db_t *db;
char *p;
if (event->key == JINGLE_KEY) {
return;
}
if (status && !strcasecmp(status, "n/a")) {
status = show;
if (status && !strcasecmp(status, "n/a")) {
status = NULL;
}
}
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
if (!status) {
status = "Available";
}
break;
case SWITCH_EVENT_PRESENCE_OUT:
type = "unavailable";
break;
default:
break;
}
if ((p = strchr(from, '/'))) {
*p = '\0';
}
sql = switch_core_db_mprintf("select *,'%q','%q' from subscriptions where sub_to='%q'", type ? type : "", status ? status : "unavailable", from);
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (struct mdl_profile *) val;
char *errmsg;
if (!(profile->user_flags & LDL_FLAG_COMPONENT)) {
continue;
}
if (sql) {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
continue;
}
switch_mutex_lock(profile->mutex);
switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->mutex);
switch_core_db_close(db);
}
}
switch_safe_free(sql);
}
static void chat_event_handler(switch_event_t *event)
{
char *from = switch_event_get_header(event, "from");
char *to = switch_event_get_header(event, "to");
char *body = switch_event_get_body(event);
char *user, *host, *f_user, *f_host = NULL;
struct mdl_profile *profile = NULL;
if (from && (f_user = strdup(from))) {
if ((f_host = strchr(f_user, '@'))) {
*f_host++ = '\0';
}
}
if (to && (user = strdup(to))) {
if ((host = strchr(user, '@'))) {
*host++ = '\0';
}
if (f_host && (profile = switch_core_hash_find(globals.profile_hash, f_host))) {
ldl_handle_send_msg(profile->handle, from, to, NULL, body);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL");
return;
}
switch_safe_free(f_host);
free(user);
}
}
static void roster_event_handler(switch_event_t *event)
{
char *status= switch_event_get_header(event, "status");
char *show= switch_event_get_header(event, "show");
char *event_type = switch_event_get_header(event, "event_type");
struct mdl_profile *profile = NULL;
switch_hash_index_t *hi;
void *val;
char *sql;
switch_core_db_t *db;
if (event->key == JINGLE_KEY) {
return;
}
if (status && !strcasecmp(status, "n/a")) {
status = show;
if (status && !strcasecmp(status, "n/a")) {
status = NULL;
}
}
if (switch_strlen_zero(event_type)) {
event_type="presence";
}
sql = switch_core_db_mprintf("select *,'%q' from subscriptions", show ? show : "unavilable");
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (struct mdl_profile *) val;
char *errmsg;
if (!(profile->user_flags & LDL_FLAG_COMPONENT)) {
continue;
}
if (sql) {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
continue;
}
switch_mutex_lock(profile->mutex);
switch_core_db_exec(db, sql, rost_callback, profile, &errmsg);
switch_mutex_unlock(profile->mutex);
switch_core_db_close(db);
}
}
switch_safe_free(sql);
}
static void terminate_session(switch_core_session_t **session, int line, switch_call_cause_t cause)
{
if (*session) {
@ -645,7 +850,7 @@ static switch_status_t channel_on_ring(switch_core_session_t *session)
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL RING\n", switch_channel_get_name(channel));
return SWITCH_STATUS_SUCCESS;
@ -1079,6 +1284,7 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session,
char sess_id[11] = "";
char *dnis = NULL;
char workspace[1024] = "";
char *p, *u, ubuf[512] = "", *user = NULL;;
switch_copy_string(workspace, outbound_profile->destination_number, sizeof(workspace));
profile_name = workspace;
@ -1094,13 +1300,23 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session,
*dnis++ = '\0';
}
if ((p = strchr(profile_name, '@'))) {
*p++ = '\0';
u = profile_name;
profile_name = p;
snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name);
user = ubuf;
} else {
user = mdl_profile->login;
}
if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
if (!ldl_handle_ready(mdl_profile->handle)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doh! we are not logged in yet!\n");
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return SWITCH_STATUS_GENERR;
}
if (!(full_id = ldl_handle_probe(mdl_profile->handle, callto, idbuf, sizeof(idbuf)))) {
if (!(full_id = ldl_handle_probe(mdl_profile->handle, callto, user, idbuf, sizeof(idbuf)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unknown Recipient!\n");
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return SWITCH_STATUS_GENERR;
@ -1151,7 +1367,7 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session,
switch_stun_random_string(sess_id, 10, "0123456789");
ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, mdl_profile->login);
ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, user);
tech_pvt->profile = mdl_profile;
ldl_session_set_private(dlsession, *new_session);
ldl_session_set_value(dlsession, "dnis", dnis);
@ -1195,6 +1411,26 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_CONNECTED);
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, roster_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, chat_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &channel_module_interface;
@ -1323,6 +1559,25 @@ static void set_profile_val(struct mdl_profile *profile, char *var, char *val)
if (switch_true(val)) {
profile->user_flags |= LDL_FLAG_TLS;
}
} else if (!strcasecmp(var, "component")) {
if (switch_true(val)) {
char dbname[256];
switch_core_db_t *db;
profile->user_flags |= LDL_FLAG_COMPONENT;
switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
profile->dbname = switch_core_strdup(module_pool, dbname);
if ((db = switch_core_db_open_file(profile->dbname))) {
switch_core_db_test_reactive(db, "select * from subscriptions", sub_sql);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
return;
}
switch_core_db_close(db);
}
} else if (!strcasecmp(var, "sasl")) {
if (!strcasecmp(val, "plain")) {
profile->user_flags |= LDL_FLAG_SASL_PLAIN;
@ -1510,8 +1765,29 @@ static switch_status_t load_config(void)
}
static void execute_sql(char *dbname, char *sql, switch_mutex_t *mutex)
{
switch_core_db_t *db;
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg)
if (mutex) {
switch_mutex_lock(mutex);
}
if (!(db = switch_core_db_open_file(dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", dbname);
goto end;
}
switch_core_db_persistant_execute(db, sql, 25);
switch_core_db_close(db);
end:
if (mutex) {
switch_mutex_unlock(mutex);
}
}
static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *to, char *from, char *subject, char *msg)
{
struct mdl_profile *profile = NULL;
switch_core_session_t *session = NULL;
@ -1519,7 +1795,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
struct private_object *tech_pvt = NULL;
switch_event_t *event;
ldl_status status = LDL_STATUS_SUCCESS;
char *sql;
assert(handle != NULL);
if (!(profile = ldl_handle_get_private(handle))) {
@ -1530,6 +1807,32 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
if (!dlsession) {
switch(signal) {
case LDL_SIGNAL_UNSUBSCRIBE:
if ((profile->user_flags & LDL_FLAG_COMPONENT)) {
if ((sql = switch_core_db_mprintf("delete from subscriptions where sub_from='%q' and sub_to='%q';", from, to))) {
execute_sql(profile->dbname, sql, profile->mutex);
switch_core_db_free(sql);
}
}
break;
case LDL_SIGNAL_SUBSCRIBE:
if ((profile->user_flags & LDL_FLAG_COMPONENT)) {
if ((sql = switch_core_db_mprintf("insert into subscriptions values('%q','%q')", from, to))) {
execute_sql(profile->dbname, sql, profile->mutex);
switch_core_db_free(sql);
}
}
break;
case LDL_SIGNAL_ROSTER:
if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle");
//event->key = JINGLE_KEY;
switch_event_fire(&event);
}
break;
case LDL_SIGNAL_PRESENCE_IN:
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle");
@ -1537,14 +1840,17 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", subject);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", msg);
//event->key = JINGLE_KEY;
switch_event_fire(&event);
}
break;
case LDL_SIGNAL_PRESENCE_OUT:
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
//event->key = JINGLE_KEY;
switch_event_fire(&event);
}
break;
@ -1553,13 +1859,15 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "%s", subject);
event->key = JINGLE_KEY;
if (msg) {
switch_event_add_body(event, msg);
}
if (profile->auto_reply) {
ldl_handle_send_msg(handle, from, "", profile->auto_reply);
ldl_handle_send_msg(handle, (profile->user_flags & LDL_FLAG_COMPONENT) ? to : profile->login, from, "", profile->auto_reply);
}
switch_event_fire(&event);
@ -1666,6 +1974,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "%s", subject);
if (msg) {
switch_event_add_body(event, msg);
@ -1803,6 +2112,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
char *context;
char *cid_name;
char *cid_num;
char *t, *them = NULL;
memset(payloads, 0, sizeof(payloads));
@ -1814,6 +2124,18 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
if (!(exten = ldl_session_get_value(dlsession, "dnis"))) {
exten = profile->exten;
if (!strcmp(exten, "_auto_")) {
if ((t = ldl_session_get_callee(dlsession))) {
if ((them = strdup(t))) {
char *p;
if ((p = strchr(them, '/'))) {
*p = '\0';
}
exten = them;
}
}
}
}
if (!(context = ldl_session_get_value(dlsession, "context"))) {
@ -1851,6 +2173,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
}
}
switch_safe_free(them);
if (lanaddr) {
switch_set_flag_locked(tech_pvt, TFLAG_LANADDR);
}

View File

@ -24,6 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
*
*
* mod_sofia.c -- SOFIA SIP Endpoint
@ -66,7 +67,7 @@ typedef struct private_object private_object_t;
#define MULTICAST_EVENT "multicast::event"
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
#define SOFIA_USER_AGENT "FreeSWITCH(mod_sofia)"
#define SIP_KEY 2
#include <sofia-sip/nua.h>
#include <sofia-sip/sip_status.h>
@ -251,6 +252,8 @@ struct sofia_profile {
outbound_reg_t *registrations;
sip_presence_t *presence;
su_home_t *home;
switch_hash_t *profile_hash;
switch_hash_t *chat_hash;
};
@ -296,6 +299,10 @@ struct private_object {
char *xferto;
char *kick;
char *origin;
char *hash_key;
char *chat_from;
char *chat_to;
char *e_dest;
unsigned long rm_rate;
switch_payload_t pt;
switch_mutex_t *flag_mutex;
@ -530,7 +537,6 @@ static void execute_sql(char *dbname, char *sql, switch_mutex_t *mutex)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", dbname);
goto end;
}
switch_core_db_persistant_execute(db, sql, 25);
switch_core_db_close(db);
@ -840,12 +846,57 @@ static switch_status_t tech_choose_port(private_object_t *tech_pvt)
return SWITCH_STATUS_SUCCESS;
}
char *encode_name(char *s)
{
char *ss, *sret;
uint32_t len;
char *at, *resource;
char *user;
if (!strchr(s, '/') && !strchr(s, '@')) {
return NULL;
}
if (!(ss = strdup(s))) {
return NULL;
}
user = ss;
resource = strchr(user, '/');
at = strchr(user, '@');
if (resource) {
*resource++ = '\0';
}
len = strlen(user) + 25;
if (at) {
*at++ = '\0';
}
if (!(sret = (char *) malloc(len))) {
return NULL;
}
memset(sret, 0, len);
snprintf(sret, len, "jingle+%s+%s", user, at);
free(ss);
return sret;
}
static void do_invite(switch_core_session_t *session)
{
char rpid[1024];
private_object_t *tech_pvt;
switch_channel_t *channel = NULL;
switch_caller_profile_t *caller_profile;
char *cid_name, *cid_num_p = NULL, *cid_num;
char *e_dest = NULL;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
@ -855,16 +906,22 @@ static void do_invite(switch_core_session_t *session)
caller_profile = switch_channel_get_caller_profile(channel);
cid_name = (char *) caller_profile->caller_id_name;
cid_num = (char *) caller_profile->caller_id_number;
if ((cid_num_p = encode_name(cid_num))) {
cid_num = cid_num_p;
}
if ((tech_pvt->from_str = switch_core_db_mprintf("\"%s\" <sip:%s@%s>",
(char *) caller_profile->caller_id_name,
(char *) caller_profile->caller_id_number,
cid_name,
cid_num,
tech_pvt->profile->sipip
))) {
char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
tech_choose_port(tech_pvt);
set_local_sdp(tech_pvt);
@ -899,6 +956,23 @@ static void do_invite(switch_core_session_t *session)
}
if ((e_dest = strdup(tech_pvt->e_dest))) {
char *user = e_dest, *host = NULL;
char hash_key[256] = "";
if ((host = strchr(user, '@'))) {
*host++ = '\0';
}
snprintf(hash_key, sizeof(hash_key), "%s%s%s", user, host, cid_num);
tech_pvt->chat_from = tech_pvt->from_str;
tech_pvt->chat_to = tech_pvt->dest;
tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key);
switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt);
}
nua_invite(tech_pvt->nh,
TAG_IF(rpid, SIPTAG_HEADER_STR(rpid)),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
@ -910,6 +984,8 @@ static void do_invite(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
}
switch_safe_free(cid_num_p);
}
@ -982,6 +1058,7 @@ static switch_status_t sofia_on_init(switch_core_session_t *session)
tech_pvt->read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
switch_channel_set_variable(channel, "endpoint_disposition", "INIT");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SOFIA INIT\n");
@ -1113,6 +1190,9 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel %s hanging up, cause: %s\n",
switch_channel_get_name(channel), switch_channel_cause2str(cause), sip_cause);
if (tech_pvt->hash_key) {
switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->hash_key);
}
if (tech_pvt->kick && (asession = switch_core_session_locate(tech_pvt->kick))) {
switch_channel_t *a_channel = switch_core_session_get_channel(asession);
@ -1714,6 +1794,42 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t sofia_receive_event(switch_core_session_t *session, switch_event_t *event)
{
switch_channel_t *channel;
struct private_object *tech_pvt;
char *body;
nua_handle_t *msg_nh;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
if (!(body = switch_event_get_body(event))) {
body = "";
}
if (tech_pvt->hash_key) {
msg_nh = nua_handle(tech_pvt->profile->nua, NULL,
SIPTAG_FROM_STR(tech_pvt->chat_from),
NUTAG_URL(tech_pvt->chat_to),
SIPTAG_TO_STR(tech_pvt->chat_to),
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
TAG_END());
nua_message(msg_nh,
SIPTAG_CONTENT_TYPE_STR("text/html"),
SIPTAG_PAYLOAD_STR(body),
TAG_END());
}
return SWITCH_STATUS_SUCCESS;
}
static const switch_io_routines_t sofia_io_routines = {
/*.outgoing_channel */ sofia_outgoing_channel,
/*.answer_channel */ sofia_answer_channel,
@ -1723,7 +1839,8 @@ static const switch_io_routines_t sofia_io_routines = {
/*.waitfor_read */ sofia_waitfor_read,
/*.waitfor_read */ sofia_waitfor_write,
/*.send_dtmf*/ sofia_send_dtmf,
/*.receive_message*/ sofia_receive_message
/*.receive_message*/ sofia_receive_message,
/*.receive_event*/ sofia_receive_event
};
static const switch_state_handler_table_t sofia_event_handlers = {
@ -1823,6 +1940,8 @@ static switch_status_t sofia_outgoing_channel(switch_core_session_t *session, sw
if ((host = strchr(dest, '%'))) {
char buf[128];
*host = '@';
tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
*host++ = '\0';
if (find_reg_url(profile, dest, host, buf, sizeof(buf))) {
tech_pvt->dest = switch_core_session_strdup(nsession, buf);
@ -1976,6 +2095,57 @@ static switch_call_cause_t sip_cause_to_freeswitch(int status) {
}
}
static void set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
{
snprintf(hash_key, len, "%s%s%s",
(char *) sip->sip_from->a_url->url_user,
(char *) sip->sip_from->a_url->url_host,
(char *) sip->sip_to->a_url->url_user
);
#if 0
/* nicer one we cant use in both directions >=0 */
snprintf(hash_key, len, "%s%s%s%s%s%s",
(char *) sip->sip_to->a_url->url_user,
(char *) sip->sip_to->a_url->url_host,
(char *) sip->sip_to->a_url->url_params,
(char *) sip->sip_from->a_url->url_user,
(char *) sip->sip_from->a_url->url_host,
(char *) sip->sip_from->a_url->url_params
);
#endif
}
static void set_chat_hash(private_object_t *tech_pvt, sip_t const *sip)
{
char hash_key[256] = "";
char buf[512];
if (!sip || tech_pvt->hash_key) {
return;
}
if (find_reg_url(tech_pvt->profile, (char *) sip->sip_from->a_url->url_user, (char *) sip->sip_from->a_url->url_host, buf, sizeof(buf))) {
tech_pvt->chat_from = sip_header_as_string(tech_pvt->home, (void *)sip->sip_to);
tech_pvt->chat_to = switch_core_session_strdup(tech_pvt->session, buf);
set_hash_key(hash_key, sizeof(hash_key), sip);
} else {
return;
}
tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key);
switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt);
}
static void sip_i_message(int status,
char const *phrase,
nua_t *nua,
@ -1995,7 +2165,7 @@ static void sip_i_message(int status,
sip_subject_t const *sip_subject = sip->sip_subject;
sip_payload_t *payload = sip->sip_payload;
const char *subject = "n/a";
char *msg = "";
char *msg = NULL;
if (strstr((char*)sip->sip_content_type->c_subtype, "composing")) {
return;
@ -2020,34 +2190,71 @@ static void sip_i_message(int status,
}
if (nh) {
char *message = "<b>hello world</b>";
char buf[256] = "";
char hash_key[512];
private_object_t *tech_pvt;
switch_channel_t *channel;
switch_event_t *event;
char *to_addr;
char *from_addr;
char *p;
if (find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
nua_handle_t *msg_nh;
if ((p=strchr(to_user, '+'))) {
if ((to_addr = strdup(++p))) {
p = strchr(to_addr, '+');
*p = '@';
}
} else {
to_addr = switch_core_db_mprintf("%s@%s", to_user, to_host);
}
from_addr = switch_core_db_mprintf("%s@%s", from_user, from_host);
msg_nh = nua_handle(profile->nua, NULL,
SIPTAG_FROM(sip->sip_to),
SIPTAG_TO_STR(buf),
SIPTAG_CONTACT_STR(profile->url),
TAG_END());
set_hash_key(hash_key, sizeof(hash_key), sip);
if ((tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
channel = switch_core_session_get_channel(tech_pvt->session);
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", tech_pvt->hash_key);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to_addr);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
event->key = SIP_KEY;
if (msg) {
switch_event_add_body(event, msg);
}
if (switch_core_session_queue_event(tech_pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
switch_event_fire(&event);
}
}
} else {
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from_addr);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to_addr);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
event->key = SIP_KEY;
if (msg) {
switch_event_add_body(event, msg);
}
nua_message(msg_nh,
SIPTAG_CONTENT_TYPE_STR("text/html"),
TAG_IF(message,
SIPTAG_PAYLOAD_STR(message)),
TAG_END());
switch_event_fire(&event);
}
}
}
//printf("==================================\nFrom: %s@%s\nSubject: %s\n\n%s\n\n",from_user,from_host,subject,msg);
switch_safe_free(to_addr);
switch_safe_free(from_addr);
}
}
}
static void sip_i_state(int status,
char const *phrase,
nua_t *nua,
@ -2089,6 +2296,8 @@ static void sip_i_state(int status,
tech_pvt->nh = nh;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel %s entering state [%s]\n",
switch_channel_get_name(channel),
nua_callstate_name(ss_state));
@ -2097,6 +2306,7 @@ static void sip_i_state(int status,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
tech_pvt->remote_sdp_str = switch_core_session_strdup(session, (char *)r_sdp);
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, (char *) r_sdp);
}
}
@ -2201,7 +2411,6 @@ static void sip_i_state(int status,
if (match) {
nua_handle_t *bnh;
sip_replaces_t *replaces;
switch_channel_set_variable(channel, "endpoint_disposition", "RECEIVED");
switch_channel_set_state(channel, CS_INIT);
switch_set_flag_locked(tech_pvt, TFLAG_READY);
@ -2447,14 +2656,22 @@ static uint8_t handle_register(nua_t *nua,
uint8_t stale = 0, ret = 0, forbidden = 0;
auth_res_t auth_res;
long exptime = 60;
switch_event_t *event;
if (sip->sip_contact) {
char *port = (char *) contact->m_url->url_port;
if (!port) {
port = "5060";
}
if (contact->m_url->url_params) {
snprintf(contact_str, sizeof(contact_str), "sip:%s@%s:%s;%s",
contact->m_url->url_user, contact->m_url->url_host, contact->m_url->url_port, contact->m_url->url_params);
contact->m_url->url_user, contact->m_url->url_host, port, contact->m_url->url_params);
} else {
snprintf(contact_str, sizeof(contact_str), "sip:%s@%s:%s",
contact->m_url->url_user, contact->m_url->url_host, contact->m_url->url_port);
contact->m_url->url_user, contact->m_url->url_host, port);
}
}
@ -2600,7 +2817,6 @@ static uint8_t handle_register(nua_t *nua,
}
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
@ -2623,6 +2839,38 @@ static uint8_t handle_register(nua_t *nua,
(long)exptime
);
if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
event->key = SIP_KEY;
switch_event_fire(&event);
}
if (exptime) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "Registered");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
} else {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "unavailable");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
}
if (regtype == REG_REGISTER) {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact),
NUTAG_WITH_THIS(nua),
@ -2667,14 +2915,19 @@ static void sip_i_subscribe(int status,
}
if (contact) {
char *port = (char *) contact->m_url->url_port;
if (!port) {
port = "5060";
}
if (contact->m_url->url_params) {
contact_str = switch_core_db_mprintf("sip:%s@%s:%s;%s",
contact->m_url->url_user,
contact->m_url->url_host, contact->m_url->url_port, contact->m_url->url_params);
contact->m_url->url_host, port, contact->m_url->url_params);
} else {
contact_str = switch_core_db_mprintf("sip:%s@%s:%s",
contact->m_url->url_user,
contact->m_url->url_host, contact->m_url->url_port);
contact->m_url->url_host, port);
}
}
@ -2737,9 +2990,7 @@ static void sip_i_subscribe(int status,
switch_core_db_free(sql);
}
nua_respond(nh, SIP_202_ACCEPTED,
SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=3600"),
SIPTAG_FROM(sip->sip_to),
@ -3095,8 +3346,9 @@ static void sip_i_publish(nua_t *nua,
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", note_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", note_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", status_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
switch_event_fire(&event);
}
@ -3105,6 +3357,7 @@ static void sip_i_publish(nua_t *nua,
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
switch_event_fire(&event);
}
@ -3213,10 +3466,13 @@ static void sip_i_invite(nua_t *nua,
return;
}
attach_private(session, profile, tech_pvt, username);
channel = switch_core_session_get_channel(session);
switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
set_chat_hash(tech_pvt, sip);
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
(char *) from->a_url->url_user,
@ -3743,6 +3999,11 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Creating presence for %s\n", profile->url);
}
switch_mutex_lock(globals.hash_mutex);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_mutex_unlock(globals.hash_mutex);
while(globals.running == 1) {
if (++ireg_loops >= IREG_SECONDS) {
check_expire(profile, time(NULL));
@ -3784,9 +4045,6 @@ static void launch_profile_thread(sofia_profile_t *profile)
switch_threadattr_create(&thd_attr, profile->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_mutex_lock(globals.hash_mutex);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_mutex_unlock(globals.hash_mutex);
switch_thread_create(&thread, thd_attr, profile_thread_run, profile, profile->pool);
}
@ -3851,6 +4109,7 @@ static switch_status_t config_sofia(int reload)
profile->name = switch_core_strdup(profile->pool, xprofilename);
snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
profile->dbname = switch_core_strdup(profile->pool, url);
switch_core_hash_init(&profile->chat_hash, profile->pool);
profile->dtmf_duration = 100;
profile->codec_ms = 20;
@ -3970,7 +4229,7 @@ static switch_status_t config_sofia(int reload)
profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
}
snprintf(url, sizeof(url), "sip:%s@%s:%d", profile->name, profile->sipip, profile->sip_port);
snprintf(url, sizeof(url), "sip:mod_sofia@%s:%d", profile->sipip, profile->sip_port);
profile->url = switch_core_strdup(profile->pool, url);
}
if (profile) {
@ -4044,6 +4303,7 @@ static switch_status_t config_sofia(int reload)
}
oreg->next = profile->registrations;
profile->registrations = oreg;
}
}
}
@ -4192,7 +4452,61 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames){
return 0;
}
static void msg_event_handler(switch_event_t *event)
static void chat_event_handler(switch_event_t *event)
{
char *from = switch_event_get_header(event, "from");
char *to = switch_event_get_header(event, "to");
char *body = switch_event_get_body(event);
char buf[256];
char *user, *host;
sofia_profile_t *profile;
char *from_p = NULL, *from_pp = NULL;
if (event->key == SIP_KEY) {
return;
}
if (to && (user = strdup(to))) {
if ((host = strchr(user, '@'))) {
*host++ = '\0';
}
if (!host || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, host))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", host ? host : "NULL");
return;
}
if (find_reg_url(profile, user, host, buf, sizeof(buf))) {
nua_handle_t *msg_nh;
if ((from_p = encode_name(from))) {
from_pp = switch_core_db_mprintf("\"%s\" <sip:%s@%s>", from, from_p, host);
from = from_pp;
}
msg_nh = nua_handle(profile->nua, NULL,
SIPTAG_FROM_STR(from),
NUTAG_URL(buf),
SIPTAG_TO_STR(buf),
SIPTAG_CONTACT_STR(profile->url),
TAG_END());
nua_message(msg_nh,
SIPTAG_CONTENT_TYPE_STR("text/html"),
SIPTAG_PAYLOAD_STR(body),
TAG_END());
}
switch_safe_free(from_p);
switch_safe_free(from_pp);
free(user);
}
}
static void pres_event_handler(switch_event_t *event)
{
sofia_profile_t *profile;
switch_hash_index_t *hi;
@ -4207,6 +4521,36 @@ static void msg_event_handler(switch_event_t *event)
char *resource;
switch_core_db_t *db;
if (event->key == SIP_KEY) {
return;
}
if (event->event_id == SWITCH_EVENT_ROSTER) {
sql = switch_core_db_mprintf("select 1,'%q',* from sip_subscriptions where event='presence'", status ? status : "Available");
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
if (!(profile->pflags & PFLAG_PRESENCE)) {
continue;
}
if (sql) {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
continue;
}
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db);
}
}
return;
}
if (status && !strcasecmp(status, "n/a")) {
status = show;
if (status && !strcasecmp(status, "n/a")) {
@ -4237,6 +4581,8 @@ static void msg_event_handler(switch_event_t *event)
return;
}
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
if (!status) {
@ -4308,17 +4654,22 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
config_sofia(0);
if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, chat_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind((char *) modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}

View File

@ -1315,19 +1315,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core
if (endpoint_interface->io_routines->outgoing_channel) {
if (session) {
char *ecaller_id_name = NULL, *ecaller_id_number = NULL;
channel = switch_core_session_get_channel(session);
if (caller_profile) {
char *ecaller_id_name = NULL, *ecaller_id_number = NULL;
ecaller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name");
ecaller_id_number = switch_channel_get_variable(channel, "effective_caller_id_number");
ecaller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name");
ecaller_id_number = switch_channel_get_variable(channel, "effective_caller_id_number");
if (ecaller_id_name || ecaller_id_number) {
if (caller_profile) {
if (ecaller_id_name || ecaller_id_number) {
outgoing_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
caller_profile->username,
caller_profile->dialplan,
ecaller_id_name ? ecaller_id_name : caller_profile->caller_id_name,
ecaller_id_number ? ecaller_id_number : caller_profile->caller_id_number,
ecaller_id_name,
ecaller_id_number,
caller_profile->network_addr,
caller_profile->ani,
caller_profile->aniii,
@ -1336,7 +1336,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core
caller_profile->context,
caller_profile->destination_number);
outgoing_profile->flags = caller_profile->flags;
}
}
}
if (!outgoing_profile) {
outgoing_profile = switch_channel_get_caller_profile(channel);
}
}
@ -1361,14 +1364,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core
if (*new_session) {
switch_caller_profile_t *profile = NULL, *peer_profile = NULL, *cloned_profile = NULL;
switch_channel_t *peer_channel = NULL;
switch_event_t *event;
switch_channel_t *new_channel = switch_core_session_get_channel(*new_session);
switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session);
if (session && channel) {
profile = switch_channel_get_caller_profile(channel);
}
if ((peer_channel = switch_core_session_get_channel(*new_session)) != 0) {
if (peer_channel) {
peer_profile = switch_channel_get_caller_profile(peer_channel);
}
@ -1386,7 +1388,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core
}
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_OUTGOING) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(new_channel, event);
switch_channel_event_set_data(peer_channel, event);
switch_event_fire(&event);
}
}

View File

@ -125,6 +125,7 @@ static char *EVENT_NAMES[] = {
"MESSAGE",
"PRESENCE_IN",
"PRESENCE_OUT",
"ROSTER",
"CODEC",
"BACKGROUND_JOB",
"ALL"
@ -587,6 +588,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_dup(switch_event_t **event, switch_
(*event)->body = DUP(todup->body);
}
(*event)->key = todup->key;
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1823,6 +1823,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
caller_caller_profile->source,
caller_caller_profile->context,
chan_data);
caller_profiles[i]->flags = caller_caller_profile->flags;
pool = NULL;
} else {
if (!cid_name_override) {